summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/auto.pro11
-rw-r--r--tests/auto/multimedia.pro41
-rw-r--r--tests/auto/qabstractvideobuffer/qabstractvideobuffer.pro9
-rw-r--r--tests/auto/qabstractvideobuffer/tst_qabstractvideobuffer.cpp134
-rw-r--r--tests/auto/qabstractvideosurface/qabstractvideosurface.pro9
-rw-r--r--tests/auto/qabstractvideosurface/tst_qabstractvideosurface.cpp312
-rw-r--r--tests/auto/qaudiocapturesource/qaudiocapturesource.pro9
-rw-r--r--tests/auto/qaudiocapturesource/tst_qaudiocapturesource.cpp360
-rw-r--r--tests/auto/qaudiodeviceinfo/qaudiodeviceinfo.pro9
-rw-r--r--tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp207
-rw-r--r--tests/auto/qaudioformat/qaudioformat.pro9
-rw-r--r--tests/auto/qaudioformat/tst_qaudioformat.cpp184
-rw-r--r--tests/auto/qaudioinput/qaudioinput.pro18
-rwxr-xr-xtests/auto/qaudioinput/tst_qaudioinput.cpp814
-rwxr-xr-xtests/auto/qaudioinput/wavheader.cpp205
-rwxr-xr-xtests/auto/qaudioinput/wavheader.h80
-rw-r--r--tests/auto/qaudiooutput/qaudiooutput.pro18
-rwxr-xr-xtests/auto/qaudiooutput/tst_qaudiooutput.cpp962
-rwxr-xr-xtests/auto/qaudiooutput/wavheader.cpp205
-rwxr-xr-xtests/auto/qaudiooutput/wavheader.h80
-rw-r--r--tests/auto/qcamera/qcamera.pro15
-rw-r--r--tests/auto/qcamera/tst_qcamera.cpp2012
-rw-r--r--tests/auto/qcamerabackend/qcamerabackend.pro15
-rw-r--r--tests/auto/qcamerabackend/tst_qcamerabackend.cpp633
-rw-r--r--tests/auto/qdeclarativeaudio/qdeclarativeaudio.pro18
-rw-r--r--tests/auto/qdeclarativeaudio/tst_qdeclarativeaudio.cpp1302
-rw-r--r--tests/auto/qdeclarativevideo/qdeclarativevideo.pro18
-rw-r--r--tests/auto/qdeclarativevideo/tst_qdeclarativevideo.cpp992
-rw-r--r--tests/auto/qgraphicsvideoitem/qgraphicsvideoitem.pro12
-rw-r--r--tests/auto/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp675
-rw-r--r--tests/auto/qmediacontent/qmediacontent.pro7
-rw-r--r--tests/auto/qmediacontent/tst_qmediacontent.cpp176
-rw-r--r--tests/auto/qmediaimageviewer/images.qrc9
-rw-r--r--tests/auto/qmediaimageviewer/images/coverart.pngbin0 -> 230 bytes
-rw-r--r--tests/auto/qmediaimageviewer/images/image.jpgbin0 -> 2045 bytes
-rw-r--r--tests/auto/qmediaimageviewer/images/image.pngbin0 -> 230 bytes
-rw-r--r--tests/auto/qmediaimageviewer/images/invalid.png2
-rw-r--r--tests/auto/qmediaimageviewer/images/poster.pngbin0 -> 230 bytes
-rw-r--r--tests/auto/qmediaimageviewer/qmediaimageviewer.pro17
-rw-r--r--tests/auto/qmediaimageviewer/tst_qmediaimageviewer.cpp1036
-rw-r--r--tests/auto/qmediaobject/main.cpp77
-rw-r--r--tests/auto/qmediaobject/qmediaobject.pro27
-rw-r--r--tests/auto/qmediaobject/tst_qmediaobject.cpp359
-rw-r--r--tests/auto/qmediaobject/tst_qmediaobject.h177
-rw-r--r--tests/auto/qmediaobject/tst_qmediaobject_mmf.cpp278
-rw-r--r--tests/auto/qmediaobject/tst_qmediaobject_mmf.h81
-rw-r--r--tests/auto/qmediaobject/tst_qmediaobject_xa.cpp158
-rw-r--r--tests/auto/qmediaobject/tst_qmediaobject_xa.h83
-rwxr-xr-xtests/auto/qmediaplayer/main.cpp78
-rw-r--r--tests/auto/qmediaplayer/qmediaplayer.pro25
-rw-r--r--tests/auto/qmediaplayer/tst_qmediaplayer.cpp1019
-rwxr-xr-xtests/auto/qmediaplayer/tst_qmediaplayer.h435
-rwxr-xr-xtests/auto/qmediaplayer/tst_qmediaplayer_s60.cpp1708
-rwxr-xr-xtests/auto/qmediaplayer/tst_qmediaplayer_s60.h137
-rw-r--r--tests/auto/qmediaplayer/tst_qmediaplayer_xa.cpp1413
-rw-r--r--tests/auto/qmediaplayer/tst_qmediaplayer_xa.h194
-rw-r--r--tests/auto/qmediaplayerbackend/qmediaplayerbackend.pro23
-rw-r--r--tests/auto/qmediaplayerbackend/testdata/test.wavbin0 -> 88232 bytes
-rw-r--r--tests/auto/qmediaplayerbackend/tst_qmediaplayerbackend.cpp462
-rw-r--r--tests/auto/qmediaplaylist/qmediaplaylist.pro29
-rw-r--r--tests/auto/qmediaplaylist/testdata/test.m3u11
-rw-r--r--tests/auto/qmediaplaylist/testdata/testfile0
-rw-r--r--tests/auto/qmediaplaylist/testdata/testfile2#suffix0
-rw-r--r--tests/auto/qmediaplaylist/tst_qmediaplaylist.cpp666
-rw-r--r--tests/auto/qmediaplaylistnavigator/qmediaplaylistnavigator.pro9
-rw-r--r--tests/auto/qmediaplaylistnavigator/tst_qmediaplaylistnavigator.cpp318
-rw-r--r--tests/auto/qmediapluginloader/qmediapluginloader.pro15
-rw-r--r--tests/auto/qmediapluginloader/tst_qmediapluginloader.cpp123
-rwxr-xr-xtests/auto/qmediarecorder/main.cpp80
-rw-r--r--tests/auto/qmediarecorder/qmediarecorder.pro18
-rwxr-xr-xtests/auto/qmediarecorder/s60common.h61
-rw-r--r--tests/auto/qmediarecorder/tst_qmediarecorder.cpp796
-rwxr-xr-xtests/auto/qmediarecorder/tst_qmediarecorder.h516
-rwxr-xr-xtests/auto/qmediarecorder/tst_qmediarecorder_mmf.cpp180
-rwxr-xr-xtests/auto/qmediarecorder/tst_qmediarecorder_mmf.h85
-rwxr-xr-xtests/auto/qmediarecorder/tst_qmediarecorder_xa.cpp323
-rwxr-xr-xtests/auto/qmediarecorder/tst_qmediarecorder_xa.h78
-rw-r--r--tests/auto/qmediaresource/qmediaresource.pro9
-rw-r--r--tests/auto/qmediaresource/tst_qmediaresource.cpp528
-rw-r--r--tests/auto/qmediaservice/qmediaservice.pro9
-rw-r--r--tests/auto/qmediaservice/tst_qmediaservice.cpp196
-rw-r--r--tests/auto/qmediaserviceprovider/qmediaserviceprovider.pro9
-rw-r--r--tests/auto/qmediaserviceprovider/tst_qmediaserviceprovider.cpp489
-rw-r--r--tests/auto/qmediatimerange/qmediatimerange.pro9
-rw-r--r--tests/auto/qmediatimerange/tst_qmediatimerange.cpp739
-rw-r--r--tests/auto/qpaintervideosurface/qpaintervideosurface.pro11
-rw-r--r--tests/auto/qpaintervideosurface/tst_qpaintervideosurface.cpp1249
-rwxr-xr-xtests/auto/qradiotuner/main.cpp79
-rw-r--r--tests/auto/qradiotuner/qradiotuner.pro19
-rw-r--r--tests/auto/qradiotuner/tst_qradiotuner.cpp275
-rw-r--r--tests/auto/qradiotuner/tst_qradiotuner.h285
-rw-r--r--tests/auto/qradiotuner/tst_qradiotuner_s60.cpp170
-rw-r--r--tests/auto/qradiotuner/tst_qradiotuner_s60.h79
-rw-r--r--tests/auto/qradiotuner/tst_qradiotuner_xa.cpp224
-rw-r--r--tests/auto/qradiotuner/tst_qradiotuner_xa.h81
-rw-r--r--tests/auto/qvideoframe/qvideoframe.pro9
-rw-r--r--tests/auto/qvideoframe/tst_qvideoframe.cpp793
-rw-r--r--tests/auto/qvideosurfaceformat/qvideosurfaceformat.pro9
-rw-r--r--tests/auto/qvideosurfaceformat/tst_qvideosurfaceformat.cpp738
-rw-r--r--tests/auto/qvideowidget/qvideowidget.pro10
-rw-r--r--tests/auto/qvideowidget/tst_qvideowidget.cpp1567
-rw-r--r--tests/tests.pro5
102 files changed, 28248 insertions, 0 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
new file mode 100644
index 000000000..b3a5771a2
--- /dev/null
+++ b/tests/auto/auto.pro
@@ -0,0 +1,11 @@
+TEMPLATE = subdirs
+
+SUBDIRS+=multimedia.pro
+
+# These autotests consist of things such as static code checks
+# which require that the autotest is run on the same machine
+# doing the build - i.e. cross-compilation is not allowed.
+win32|mac|linux-g++* {
+ # NOTE: Disabled until we have established which tests fall into this category
+ # !contains(QT_CONFIG,embedded):!maemo5:!maemo6:SUBDIRS+=host.pro
+}
diff --git a/tests/auto/multimedia.pro b/tests/auto/multimedia.pro
new file mode 100644
index 000000000..cb6094388
--- /dev/null
+++ b/tests/auto/multimedia.pro
@@ -0,0 +1,41 @@
+# How do we require a module?
+# requires(contains(mobility_modules,multimedia))
+
+TEMPLATE = subdirs
+SUBDIRS += \
+ qabstractvideobuffer \
+ qabstractvideosurface \
+ qaudiocapturesource \
+ qgraphicsvideoitem \
+ qmediaimageviewer \
+ qmediaobject \
+ qmediaplayer \
+ qmediaplayerbackend \
+ qmediaplaylist \
+ qmediaplaylistnavigator \
+ qmediapluginloader \
+ qmediarecorder \
+ qmediaresource \
+ qmediaservice \
+ qmediaserviceprovider \
+ qmediacontent \
+ qradiotuner \
+ qcamera \
+ qpaintervideosurface \
+ qvideowidget \
+ qmediatimerange \
+ qaudiodeviceinfo \
+ qaudiooutput \
+ qaudioinput \
+ qaudioformat \
+ qvideoframe \
+ qvideosurfaceformat \
+ qcamerabackend
+
+contains (QT_CONFIG, declarative) {
+ SUBDIRS += \
+# qsoundeffect \
+ qdeclarativeaudio \
+ qdeclarativevideo
+}
+
diff --git a/tests/auto/qabstractvideobuffer/qabstractvideobuffer.pro b/tests/auto/qabstractvideobuffer/qabstractvideobuffer.pro
new file mode 100644
index 000000000..e1fa50355
--- /dev/null
+++ b/tests/auto/qabstractvideobuffer/qabstractvideobuffer.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+
+QT += core multimediakit-private
+
+# TARGET = tst_qabstractvideobuffer
+#CONFIG += testcase
+
+SOURCES += tst_qabstractvideobuffer.cpp
+
diff --git a/tests/auto/qabstractvideobuffer/tst_qabstractvideobuffer.cpp b/tests/auto/qabstractvideobuffer/tst_qabstractvideobuffer.cpp
new file mode 100644
index 000000000..7e339eefb
--- /dev/null
+++ b/tests/auto/qabstractvideobuffer/tst_qabstractvideobuffer.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include <QtTest/QtTest>
+
+#include <qabstractvideobuffer.h>
+
+class tst_QAbstractVideoBuffer : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QAbstractVideoBuffer();
+ ~tst_QAbstractVideoBuffer();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void handleType_data();
+ void handleType();
+ void handle();
+};
+
+class QtTestVideoBuffer : public QAbstractVideoBuffer
+{
+public:
+ QtTestVideoBuffer(QAbstractVideoBuffer::HandleType type) : QAbstractVideoBuffer(type) {}
+
+ MapMode mapMode() const { return NotMapped; }
+
+ uchar *map(MapMode, int *, int *) { return 0; }
+ void unmap() {}
+};
+
+tst_QAbstractVideoBuffer::tst_QAbstractVideoBuffer()
+{
+}
+
+tst_QAbstractVideoBuffer::~tst_QAbstractVideoBuffer()
+{
+}
+
+void tst_QAbstractVideoBuffer::initTestCase()
+{
+}
+
+void tst_QAbstractVideoBuffer::cleanupTestCase()
+{
+}
+
+void tst_QAbstractVideoBuffer::init()
+{
+}
+
+void tst_QAbstractVideoBuffer::cleanup()
+{
+}
+
+void tst_QAbstractVideoBuffer::handleType_data()
+{
+ QTest::addColumn<QAbstractVideoBuffer::HandleType>("type");
+
+ QTest::newRow("none")
+ << QAbstractVideoBuffer::NoHandle;
+ QTest::newRow("opengl")
+ << QAbstractVideoBuffer::GLTextureHandle;
+ QTest::newRow("user1")
+ << QAbstractVideoBuffer::UserHandle;
+ QTest::newRow("user2")
+ << QAbstractVideoBuffer::HandleType(QAbstractVideoBuffer::UserHandle + 1);
+}
+
+void tst_QAbstractVideoBuffer::handleType()
+{
+ QFETCH(QAbstractVideoBuffer::HandleType, type);
+
+ QtTestVideoBuffer buffer(type);
+
+ QCOMPARE(buffer.handleType(), type);
+}
+
+void tst_QAbstractVideoBuffer::handle()
+{
+ QtTestVideoBuffer buffer(QAbstractVideoBuffer::NoHandle);
+
+ QVERIFY(buffer.handle().isNull());
+}
+
+QTEST_MAIN(tst_QAbstractVideoBuffer)
+
+#include "tst_qabstractvideobuffer.moc"
diff --git a/tests/auto/qabstractvideosurface/qabstractvideosurface.pro b/tests/auto/qabstractvideosurface/qabstractvideosurface.pro
new file mode 100644
index 000000000..1778b566b
--- /dev/null
+++ b/tests/auto/qabstractvideosurface/qabstractvideosurface.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+
+QT += core multimediakit-private
+
+# TARGET = tst_qabstractvideosurface
+#CONFIG += testcase
+
+SOURCES += tst_qabstractvideosurface.cpp
+
diff --git a/tests/auto/qabstractvideosurface/tst_qabstractvideosurface.cpp b/tests/auto/qabstractvideosurface/tst_qabstractvideosurface.cpp
new file mode 100644
index 000000000..bef9c7f38
--- /dev/null
+++ b/tests/auto/qabstractvideosurface/tst_qabstractvideosurface.cpp
@@ -0,0 +1,312 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include <QtTest/QtTest>
+
+#include <qabstractvideosurface.h>
+#include <qvideosurfaceformat.h>
+
+class tst_QAbstractVideoSurface : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QAbstractVideoSurface();
+ ~tst_QAbstractVideoSurface();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void setError();
+ void isFormatSupported_data();
+ void isFormatSupported();
+ void nearestFormat_data();
+ void nearestFormat();
+ void start_data();
+ void start();
+};
+
+typedef QMap<QAbstractVideoBuffer::HandleType, QVideoFrame::PixelFormat> SupportedFormatMap;
+
+Q_DECLARE_METATYPE(SupportedFormatMap)
+Q_DECLARE_METATYPE(QVideoSurfaceFormat)
+Q_DECLARE_METATYPE(QAbstractVideoSurface::Error);
+
+class QtTestVideoSurface : public QAbstractVideoSurface
+{
+ Q_OBJECT
+public:
+ explicit QtTestVideoSurface(QObject *parent = 0) : QAbstractVideoSurface(parent) {}
+ explicit QtTestVideoSurface(SupportedFormatMap formats, QObject *parent = 0)
+ : QAbstractVideoSurface(parent), supportedFormats(formats) {}
+
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const
+ {
+ return supportedFormats.values(handleType);
+ }
+
+ bool present(const QVideoFrame &) { return false; }
+
+ using QAbstractVideoSurface::setError;
+
+private:
+ SupportedFormatMap supportedFormats;
+};
+
+tst_QAbstractVideoSurface::tst_QAbstractVideoSurface()
+{
+}
+
+tst_QAbstractVideoSurface::~tst_QAbstractVideoSurface()
+{
+}
+
+void tst_QAbstractVideoSurface::initTestCase()
+{
+}
+
+void tst_QAbstractVideoSurface::cleanupTestCase()
+{
+}
+
+void tst_QAbstractVideoSurface::init()
+{
+}
+
+void tst_QAbstractVideoSurface::cleanup()
+{
+}
+
+void tst_QAbstractVideoSurface::setError()
+{
+ qRegisterMetaType<QAbstractVideoSurface::Error>();
+
+ QtTestVideoSurface surface;
+
+ QCOMPARE(surface.error(), QAbstractVideoSurface::NoError);
+
+ surface.setError(QAbstractVideoSurface::StoppedError);
+ QCOMPARE(surface.error(), QAbstractVideoSurface::StoppedError);
+
+ surface.setError(QAbstractVideoSurface::ResourceError);
+ QCOMPARE(surface.error(), QAbstractVideoSurface::ResourceError);
+
+ surface.setError(QAbstractVideoSurface::NoError);
+ QCOMPARE(surface.error(), QAbstractVideoSurface::NoError);
+}
+
+void tst_QAbstractVideoSurface::isFormatSupported_data()
+{
+ QTest::addColumn<SupportedFormatMap>("supportedFormats");
+ QTest::addColumn<QVideoSurfaceFormat>("format");
+ QTest::addColumn<bool>("supported");
+
+ SupportedFormatMap formats;
+
+ QTest::newRow("no formats: rgb32")
+ << formats
+ << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_RGB32)
+ << false;
+ QTest::newRow("no formats: yv12")
+ << formats
+ << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_YV12)
+ << false;
+ QTest::newRow("no formats: rgb32 gl")
+ << formats
+ << QVideoSurfaceFormat(
+ QSize(800, 600),
+ QVideoFrame::Format_RGB32,
+ QAbstractVideoBuffer::GLTextureHandle)
+ << false;
+ QTest::newRow("no formats: rgb24 gl")
+ << formats
+ << QVideoSurfaceFormat(
+ QSize(800, 600),
+ QVideoFrame::Format_RGB24,
+ QAbstractVideoBuffer::GLTextureHandle)
+ << false;
+
+ formats.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB32);
+ formats.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB24);
+ formats.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_YUV444);
+ formats.insertMulti(QAbstractVideoBuffer::GLTextureHandle, QVideoFrame::Format_RGB32);
+
+ QTest::newRow("supported: rgb32")
+ << formats
+ << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_RGB32)
+ << true;
+ QTest::newRow("supported: rgb24")
+ << formats
+ << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_RGB24)
+ << true;
+ QTest::newRow("unsupported: yv12")
+ << formats
+ << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_YV12)
+ << false;
+ QTest::newRow("supported: rgb32 gl")
+ << formats
+ << QVideoSurfaceFormat(
+ QSize(800, 600),
+ QVideoFrame::Format_RGB32,
+ QAbstractVideoBuffer::GLTextureHandle)
+ << true;
+ QTest::newRow("unsupported: rgb24 gl")
+ << formats
+ << QVideoSurfaceFormat(
+ QSize(800, 600),
+ QVideoFrame::Format_RGB24,
+ QAbstractVideoBuffer::GLTextureHandle)
+ << false;
+ QTest::newRow("unsupported: yv12 gl")
+ << formats
+ << QVideoSurfaceFormat(
+ QSize(800, 600),
+ QVideoFrame::Format_YV12,
+ QAbstractVideoBuffer::GLTextureHandle)
+ << false;
+
+ formats.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_YV12);
+ formats.insertMulti(QAbstractVideoBuffer::GLTextureHandle, QVideoFrame::Format_RGB24);
+
+ QTest::newRow("supported: yv12")
+ << formats
+ << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_YV12)
+ << true;
+ QTest::newRow("supported: rgb24 gl")
+ << formats
+ << QVideoSurfaceFormat(
+ QSize(800, 600),
+ QVideoFrame::Format_RGB24,
+ QAbstractVideoBuffer::GLTextureHandle)
+ << true;
+}
+
+void tst_QAbstractVideoSurface::isFormatSupported()
+{
+ QFETCH(SupportedFormatMap, supportedFormats);
+ QFETCH(QVideoSurfaceFormat, format);
+ QFETCH(bool, supported);
+
+ QtTestVideoSurface surface(supportedFormats);
+
+ QCOMPARE(surface.isFormatSupported(format), supported);
+}
+
+void tst_QAbstractVideoSurface::nearestFormat_data()
+{
+ isFormatSupported_data();
+}
+
+void tst_QAbstractVideoSurface::nearestFormat()
+{
+ QFETCH(SupportedFormatMap, supportedFormats);
+ QFETCH(QVideoSurfaceFormat, format);
+ QFETCH(bool, supported);
+
+ QtTestVideoSurface surface(supportedFormats);
+
+ QCOMPARE(surface.nearestFormat(format) == format, supported);
+}
+
+void tst_QAbstractVideoSurface::start_data()
+{
+ QTest::addColumn<QVideoSurfaceFormat>("format");
+
+ QTest::newRow("rgb32") << QVideoSurfaceFormat(
+ QSize(800, 600),
+ QVideoFrame::Format_RGB32);
+ QTest::newRow("yv12") << QVideoSurfaceFormat(
+ QSize(800, 600),
+ QVideoFrame::Format_YV12);
+ QTest::newRow("rgb32 gl") << QVideoSurfaceFormat(
+ QSize(800, 600),
+ QVideoFrame::Format_RGB32,
+ QAbstractVideoBuffer::GLTextureHandle);
+}
+
+void tst_QAbstractVideoSurface::start()
+{
+ QFETCH(QVideoSurfaceFormat, format);
+
+ QtTestVideoSurface surface;
+ surface.setError(QAbstractVideoSurface::ResourceError);
+
+ QSignalSpy formatSpy(&surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)));
+ QSignalSpy activeSpy(&surface, SIGNAL(activeChanged(bool)));
+
+ QVERIFY(!surface.isActive());
+ QCOMPARE(surface.surfaceFormat(), QVideoSurfaceFormat());
+
+ QVERIFY(surface.start(format));
+
+ QVERIFY(surface.isActive());
+ QCOMPARE(surface.surfaceFormat(), format);
+
+ QCOMPARE(formatSpy.count(), 1);
+ QCOMPARE(qvariant_cast<QVideoSurfaceFormat>(formatSpy.last().at(0)), format);
+
+ QCOMPARE(activeSpy.count(), 1);
+ QCOMPARE(activeSpy.last().at(0).toBool(), true);
+
+ // error() is reset on a successful start.
+ QCOMPARE(surface.error(), QAbstractVideoSurface::NoError);
+
+ surface.stop();
+
+ QVERIFY(!surface.isActive());
+ QCOMPARE(surface.surfaceFormat(), QVideoSurfaceFormat());
+
+ QCOMPARE(formatSpy.count(), 2);
+ QCOMPARE(qvariant_cast<QVideoSurfaceFormat>(formatSpy.last().at(0)), QVideoSurfaceFormat());
+
+ QCOMPARE(activeSpy.count(), 2);
+ QCOMPARE(activeSpy.last().at(0).toBool(), false);
+}
+
+QTEST_MAIN(tst_QAbstractVideoSurface)
+
+#include "tst_qabstractvideosurface.moc"
diff --git a/tests/auto/qaudiocapturesource/qaudiocapturesource.pro b/tests/auto/qaudiocapturesource/qaudiocapturesource.pro
new file mode 100644
index 000000000..df9c70eaf
--- /dev/null
+++ b/tests/auto/qaudiocapturesource/qaudiocapturesource.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+
+QT += multimediakit-private
+
+# TARGET = tst_qaudiocapturesource
+# CONFIG += testcase
+
+SOURCES += tst_qaudiocapturesource.cpp
+
diff --git a/tests/auto/qaudiocapturesource/tst_qaudiocapturesource.cpp b/tests/auto/qaudiocapturesource/tst_qaudiocapturesource.cpp
new file mode 100644
index 000000000..c8d9d3d7d
--- /dev/null
+++ b/tests/auto/qaudiocapturesource/tst_qaudiocapturesource.cpp
@@ -0,0 +1,360 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QDebug>
+
+#include <qaudioformat.h>
+
+#include <qaudiocapturesource.h>
+#include <qaudioencodercontrol.h>
+#include <qmediarecordercontrol.h>
+#include <qaudioendpointselector.h>
+
+//TESTED_COMPONENT=src/multimedia
+
+QT_USE_NAMESPACE
+class MockAudioEncoderControl : public QAudioEncoderControl
+{
+ Q_OBJECT
+public:
+ MockAudioEncoderControl(QObject *parent = 0):
+ QAudioEncoderControl(parent)
+ {
+ m_codecs << "audio/pcm" << "audio/mpeg";
+ m_descriptions << "Pulse Code Modulation" << "mp3 format";
+ m_audioSettings.setCodec("audio/pcm");
+ m_audioSettings.setSampleRate(8000);
+ m_freqs << 8000 << 11025 << 22050 << 44100;
+ }
+
+ ~MockAudioEncoderControl() {}
+
+ QStringList supportedAudioCodecs() const { return m_codecs; }
+ QString codecDescription(const QString &codecName) const { return m_descriptions.at(m_codecs.indexOf(codecName)); }
+
+ QStringList supportedEncodingOptions(const QString &) const { return QStringList() << "bitrate"; }
+ QVariant encodingOption(const QString &, const QString &) const { return m_optionValue; }
+ void setEncodingOption(const QString &, const QString &, const QVariant &value) { m_optionValue = value; }
+
+ QList<int> supportedSampleRates(const QAudioEncoderSettings & = QAudioEncoderSettings(),
+ bool *continuous = 0) const
+ {
+ if (continuous)
+ *continuous = false;
+ return m_freqs;
+ }
+ QList<int> supportedChannelCounts(const QAudioEncoderSettings & = QAudioEncoderSettings()) const { QList<int> list; list << 1 << 2; return list; }
+
+ QAudioEncoderSettings audioSettings() const { return m_audioSettings; }
+ void setAudioSettings(const QAudioEncoderSettings &settings) { m_audioSettings = settings;}
+
+ QStringList m_codecs;
+ QStringList m_descriptions;
+
+ QAudioEncoderSettings m_audioSettings;
+
+ QList<int> m_freqs;
+ QVariant m_optionValue;
+};
+
+class MockMediaRecorderControl : public QMediaRecorderControl
+{
+ Q_OBJECT
+public:
+ MockMediaRecorderControl(QObject *parent = 0):
+ QMediaRecorderControl(parent),
+ m_state(QMediaRecorder::StoppedState),
+ m_position(0),
+ m_muted(false) {}
+
+ ~MockMediaRecorderControl() {}
+
+ QUrl outputLocation() const { return m_sink; }
+ bool setOutputLocation(const QUrl &sink) { m_sink = sink; return true; }
+ QMediaRecorder::State state() const { return m_state; }
+ qint64 duration() const { return m_position; }
+ void applySettings() {}
+ bool isMuted() const { return m_muted; }
+
+public slots:
+ void record()
+ {
+ m_state = QMediaRecorder::RecordingState;
+ m_position=1;
+ emit stateChanged(m_state);
+ emit durationChanged(m_position);
+ }
+ void pause()
+ {
+ m_state = QMediaRecorder::PausedState;
+ emit stateChanged(m_state);
+ }
+
+ void stop()
+ {
+ m_position=0;
+ m_state = QMediaRecorder::StoppedState;
+ emit stateChanged(m_state);
+ }
+
+ void setMuted(bool muted)
+ {
+ if (m_muted != muted)
+ emit mutedChanged(m_muted = muted);
+ }
+
+public:
+ QUrl m_sink;
+ QMediaRecorder::State m_state;
+ qint64 m_position;
+ bool m_muted;
+};
+
+class MockAudioEndpointSelector : public QAudioEndpointSelector
+{
+ Q_OBJECT
+public:
+ MockAudioEndpointSelector(QObject *parent):
+ QAudioEndpointSelector(parent)
+ {
+ m_names << "device1" << "device2" << "device3";
+ m_descriptions << "dev1 comment" << "dev2 comment" << "dev3 comment";
+ m_audioInput = "device1";
+ emit availableEndpointsChanged();
+ }
+ ~MockAudioEndpointSelector() {};
+
+ QList<QString> availableEndpoints() const
+ {
+ return m_names;
+ }
+
+ QString endpointDescription(const QString& name) const
+ {
+ QString desc;
+
+ for(int i = 0; i < m_names.count(); i++) {
+ if (m_names.at(i).compare(name) == 0) {
+ desc = m_descriptions.at(i);
+ break;
+ }
+ }
+ return desc;
+ }
+
+ QString defaultEndpoint() const
+ {
+ return m_names.at(0);
+ }
+
+ QString activeEndpoint() const
+ {
+ return m_audioInput;
+ }
+
+public Q_SLOTS:
+ void setActiveEndpoint(const QString& name)
+ {
+ m_audioInput = name;
+ emit activeEndpointChanged(name);
+ }
+
+private:
+ QString m_audioInput;
+ QList<QString> m_names;
+ QList<QString> m_descriptions;
+};
+
+
+class MockAudioSourceService : public QMediaService
+{
+ Q_OBJECT
+
+public:
+ MockAudioSourceService(): QMediaService(0), hasAudioDeviceControl(true)
+ {
+ mockAudioEncoderControl = new MockAudioEncoderControl(this);
+ mockMediaRecorderControl = new MockMediaRecorderControl(this);
+ mockAudioEndpointSelector = new MockAudioEndpointSelector(this);
+ }
+
+ ~MockAudioSourceService()
+ {
+ delete mockAudioEncoderControl;
+ delete mockMediaRecorderControl;
+ delete mockAudioEndpointSelector;
+ }
+
+ QMediaControl* requestControl(const char *iid)
+ {
+ if (qstrcmp(iid, QAudioEncoderControl_iid) == 0)
+ return mockAudioEncoderControl;
+
+ if (qstrcmp(iid, QMediaRecorderControl_iid) == 0)
+ return mockMediaRecorderControl;
+
+ if (hasAudioDeviceControl && qstrcmp(iid, QAudioEndpointSelector_iid) == 0)
+ return mockAudioEndpointSelector;
+
+ return 0;
+ }
+
+ void releaseControl(QMediaControl*) {}
+
+ MockAudioEncoderControl *mockAudioEncoderControl;
+ MockMediaRecorderControl *mockMediaRecorderControl;
+ MockAudioEndpointSelector *mockAudioEndpointSelector;
+ bool hasAudioDeviceControl;
+};
+
+class MockProvider : public QMediaServiceProvider
+{
+public:
+ MockProvider(MockAudioSourceService *service):mockService(service) {}
+ QMediaService *requestService(const QByteArray&, const QMediaServiceProviderHint &)
+ {
+ return mockService;
+ }
+
+ void releaseService(QMediaService *) {}
+
+ MockAudioSourceService *mockService;
+};
+
+
+class tst_QAudioCaptureSource: public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ //void testNullService();
+ //void testNullControl();
+ void testAudioSource();
+ void testOptions();
+ void testDevices();
+
+private:
+ QAudioCaptureSource *audiosource;
+ MockAudioSourceService *mockAudioSourceService;
+ MockProvider *mockProvider;
+};
+
+void tst_QAudioCaptureSource::initTestCase()
+{
+ mockAudioSourceService = new MockAudioSourceService;
+ mockProvider = new MockProvider(mockAudioSourceService);
+}
+
+void tst_QAudioCaptureSource::cleanupTestCase()
+{
+ delete audiosource;
+ delete mockProvider;
+}
+/*
+void tst_QAudioCaptureSource::testNullService()
+{
+ MockProvider provider(0);
+ QAudioCaptureSource source(0, &provider);
+
+ QCOMPARE(source.audioInputs().size(), 0);
+ QCOMPARE(source.defaultAudioInput(), QString());
+ QCOMPARE(source.activeAudioInput(), QString());
+}
+*/
+/*
+void tst_QAudioCaptureSource::testNullControl()
+{
+ MockAudioSourceService service;
+ service.hasAudioDeviceControl = false;
+ MockProvider provider(&service);
+ QAudioCaptureSource source(0, &provider);
+
+ QCOMPARE(source.audioInputs().size(), 0);
+ QCOMPARE(source.defaultAudioInput(), QString());
+ QCOMPARE(source.activeAudioInput(), QString());
+
+ QCOMPARE(source.audioDescription("blah"), QString());
+
+ QSignalSpy deviceNameSpy(&source, SIGNAL(activeAudioInputChanged(QString)));
+
+ source.setAudioInput("blah");
+ QCOMPARE(deviceNameSpy.count(), 0);
+}
+*/
+void tst_QAudioCaptureSource::testAudioSource()
+{
+ audiosource = new QAudioCaptureSource(0, mockProvider);
+
+ QCOMPARE(audiosource->service(),(QMediaService *) mockAudioSourceService);
+}
+
+void tst_QAudioCaptureSource::testOptions()
+{
+ const QString codec(QLatin1String("mp3"));
+
+ QStringList options = mockAudioSourceService->mockAudioEncoderControl->supportedEncodingOptions(codec);
+ QVERIFY(options.count() == 1);
+ mockAudioSourceService->mockAudioEncoderControl->setEncodingOption(codec, options.first(),8000);
+ QVERIFY(mockAudioSourceService->mockAudioEncoderControl->encodingOption(codec, options.first()).toInt() == 8000);
+}
+
+void tst_QAudioCaptureSource::testDevices()
+{
+ QList<QString> devices = audiosource->audioInputs();
+ QVERIFY(devices.size() > 0);
+ QVERIFY(devices.at(0).compare("device1") == 0);
+ QVERIFY(audiosource->audioDescription("device1").compare("dev1 comment") == 0);
+ QVERIFY(audiosource->defaultAudioInput() == "device1");
+
+ QSignalSpy checkSignal(audiosource, SIGNAL(activeAudioInputChanged(QString)));
+ audiosource->setAudioInput("device2");
+ QVERIFY(audiosource->activeAudioInput().compare("device2") == 0);
+ QVERIFY(checkSignal.count() == 1);
+}
+
+QTEST_MAIN(tst_QAudioCaptureSource)
+
+#include "tst_qaudiocapturesource.moc"
diff --git a/tests/auto/qaudiodeviceinfo/qaudiodeviceinfo.pro b/tests/auto/qaudiodeviceinfo/qaudiodeviceinfo.pro
new file mode 100644
index 000000000..1b2452419
--- /dev/null
+++ b/tests/auto/qaudiodeviceinfo/qaudiodeviceinfo.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+
+QT += core multimediakit-private
+
+# TARGET = tst_qaudiodeviceinfo
+# CONFIG += testcase
+
+SOURCES += tst_qaudiodeviceinfo.cpp
+
diff --git a/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp
new file mode 100644
index 000000000..29225bc62
--- /dev/null
+++ b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtCore/qlocale.h>
+#include <qaudiodeviceinfo.h>
+
+#include <QStringList>
+#include <QList>
+
+//TESTED_COMPONENT=src/multimedia
+
+class tst_QAudioDeviceInfo : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QAudioDeviceInfo(QObject* parent=0) : QObject(parent) {}
+
+private slots:
+ void initTestCase();
+ void checkAvailableDefaultInput();
+ void checkAvailableDefaultOutput();
+ void outputList();
+ void codecs();
+ void channels();
+ void sampleSizes();
+ void byteOrders();
+ void sampleTypes();
+ void frequencies();
+ void isformat();
+ void preferred();
+ void nearest();
+
+private:
+ bool available;
+ QAudioDeviceInfo* device;
+};
+
+void tst_QAudioDeviceInfo::initTestCase()
+{
+ // Only perform tests if audio output device exists!
+ QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
+ if(devices.size() > 0)
+ available = true;
+ else {
+ qWarning()<<"NOTE: no audio output device found, no test will be performed";
+ available = false;
+ }
+}
+
+void tst_QAudioDeviceInfo::checkAvailableDefaultInput()
+{
+ // Only perform tests if audio input device exists!
+ bool storeAvailable = available;
+ QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
+ if(devices.size() > 0)
+ available = true;
+ else {
+ qWarning()<<"NOTE: no audio input device found, no test will be performed";
+ available = false;
+ }
+ if(available)
+ QVERIFY(!QAudioDeviceInfo::defaultInputDevice().isNull());
+ available = storeAvailable;
+}
+
+void tst_QAudioDeviceInfo::checkAvailableDefaultOutput()
+{
+ if(available)
+ QVERIFY(!QAudioDeviceInfo::defaultOutputDevice().isNull());
+}
+
+void tst_QAudioDeviceInfo::outputList()
+{
+ if(available) {
+ QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
+ QVERIFY(devices.size() > 0);
+ device = new QAudioDeviceInfo(devices.at(0));
+ }
+}
+
+void tst_QAudioDeviceInfo::codecs()
+{
+ if(available) {
+ QStringList avail = device->supportedCodecs();
+ QVERIFY(avail.size() > 0);
+ }
+}
+
+void tst_QAudioDeviceInfo::channels()
+{
+ if(available) {
+ QList<int> avail = device->supportedChannels();
+ QVERIFY(avail.size() > 0);
+ }
+}
+
+void tst_QAudioDeviceInfo::sampleSizes()
+{
+ if(available) {
+ QList<int> avail = device->supportedSampleSizes();
+ QVERIFY(avail.size() > 0);
+ }
+}
+
+void tst_QAudioDeviceInfo::byteOrders()
+{
+ if(available) {
+ QList<QAudioFormat::Endian> avail = device->supportedByteOrders();
+ QVERIFY(avail.size() > 0);
+ }
+}
+
+void tst_QAudioDeviceInfo::sampleTypes()
+{
+ if(available) {
+ QList<QAudioFormat::SampleType> avail = device->supportedSampleTypes();
+ QVERIFY(avail.size() > 0);
+ }
+}
+
+void tst_QAudioDeviceInfo::frequencies()
+{
+ if(available) {
+ QList<int> avail = device->supportedFrequencies();
+ QVERIFY(avail.size() > 0);
+ }
+}
+
+void tst_QAudioDeviceInfo::isformat()
+{
+ if(available) {
+ QAudioFormat format;
+ format.setFrequency(44100);
+ format.setChannels(2);
+ format.setSampleType(QAudioFormat::SignedInt);
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setSampleSize(16);
+ format.setCodec("audio/pcm");
+
+ // Should always be true for these format
+ QVERIFY(device->isFormatSupported(format));
+ }
+}
+
+void tst_QAudioDeviceInfo::preferred()
+{
+ if(available) {
+ QAudioFormat format = device->preferredFormat();
+ QVERIFY(format.isValid());
+ }
+}
+
+void tst_QAudioDeviceInfo::nearest()
+{
+ if(available) {
+ /*
+ QAudioFormat format1, format2;
+ format1.setFrequency(8000);
+ format2 = device->nearestFormat(format1);
+ QVERIFY(format2.frequency() == 44100);
+ */
+ }
+}
+
+QTEST_MAIN(tst_QAudioDeviceInfo)
+
+#include "tst_qaudiodeviceinfo.moc"
diff --git a/tests/auto/qaudioformat/qaudioformat.pro b/tests/auto/qaudioformat/qaudioformat.pro
new file mode 100644
index 000000000..568cad09a
--- /dev/null
+++ b/tests/auto/qaudioformat/qaudioformat.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+
+QT += core multimediakit-private
+
+# TARGET = tst_qaudioformat
+# CONFIG += testcase
+
+SOURCES += tst_qaudioformat.cpp
+
diff --git a/tests/auto/qaudioformat/tst_qaudioformat.cpp b/tests/auto/qaudioformat/tst_qaudioformat.cpp
new file mode 100644
index 000000000..d543708ae
--- /dev/null
+++ b/tests/auto/qaudioformat/tst_qaudioformat.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtCore/qlocale.h>
+#include <qaudioformat.h>
+
+#include <QStringList>
+#include <QList>
+
+//TESTED_COMPONENT=src/multimedia
+
+class tst_QAudioFormat : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QAudioFormat(QObject* parent=0) : QObject(parent) {}
+
+private slots:
+ void checkNull();
+ void checkFrequency();
+ void checkChannels();
+ void checkSampleSize();
+ void checkCodec();
+ void checkByteOrder();
+ void checkSampleType();
+ void checkEquality();
+ void checkAssignment();
+};
+
+void tst_QAudioFormat::checkNull()
+{
+ // Default constructed QAudioFormat is invalid.
+ QAudioFormat audioFormat0;
+ QVERIFY(!audioFormat0.isValid());
+
+ // validity is transferred
+ QAudioFormat audioFormat1(audioFormat0);
+ QVERIFY(!audioFormat1.isValid());
+
+ audioFormat0.setFrequency(44100);
+ audioFormat0.setChannels(2);
+ audioFormat0.setSampleSize(16);
+ audioFormat0.setCodec("audio/pcm");
+ audioFormat0.setSampleType(QAudioFormat::SignedInt);
+ QVERIFY(audioFormat0.isValid());
+}
+
+void tst_QAudioFormat::checkFrequency()
+{
+ QAudioFormat audioFormat;
+ audioFormat.setFrequency(44100);
+ QVERIFY(audioFormat.frequency() == 44100);
+}
+
+void tst_QAudioFormat::checkChannels()
+{
+ QAudioFormat audioFormat;
+ audioFormat.setChannels(2);
+ QVERIFY(audioFormat.channels() == 2);
+}
+
+void tst_QAudioFormat::checkSampleSize()
+{
+ QAudioFormat audioFormat;
+ audioFormat.setSampleSize(16);
+ QVERIFY(audioFormat.sampleSize() == 16);
+}
+
+void tst_QAudioFormat::checkCodec()
+{
+ QAudioFormat audioFormat;
+ audioFormat.setCodec(QString::fromLatin1("audio/pcm"));
+ QVERIFY(audioFormat.codec() == QString::fromLatin1("audio/pcm"));
+}
+
+void tst_QAudioFormat::checkByteOrder()
+{
+ QAudioFormat audioFormat;
+ audioFormat.setByteOrder(QAudioFormat::LittleEndian);
+ QVERIFY(audioFormat.byteOrder() == QAudioFormat::LittleEndian);
+}
+
+void tst_QAudioFormat::checkSampleType()
+{
+ QAudioFormat audioFormat;
+ audioFormat.setSampleType(QAudioFormat::SignedInt);
+ QVERIFY(audioFormat.sampleType() == QAudioFormat::SignedInt);
+}
+
+void tst_QAudioFormat::checkEquality()
+{
+ QAudioFormat audioFormat0;
+ QAudioFormat audioFormat1;
+
+ // Null formats are equivalent
+ QVERIFY(audioFormat0 == audioFormat1);
+ QVERIFY(!(audioFormat0 != audioFormat1));
+
+ // on filled formats
+ audioFormat0.setFrequency(8000);
+ audioFormat0.setChannels(1);
+ audioFormat0.setSampleSize(8);
+ audioFormat0.setCodec("audio/pcm");
+ audioFormat0.setByteOrder(QAudioFormat::LittleEndian);
+ audioFormat0.setSampleType(QAudioFormat::UnSignedInt);
+
+ audioFormat1.setFrequency(8000);
+ audioFormat1.setChannels(1);
+ audioFormat1.setSampleSize(8);
+ audioFormat1.setCodec("audio/pcm");
+ audioFormat1.setByteOrder(QAudioFormat::LittleEndian);
+ audioFormat1.setSampleType(QAudioFormat::UnSignedInt);
+
+ QVERIFY(audioFormat0 == audioFormat1);
+ QVERIFY(!(audioFormat0 != audioFormat1));
+
+ audioFormat0.setFrequency(44100);
+ QVERIFY(audioFormat0 != audioFormat1);
+ QVERIFY(!(audioFormat0 == audioFormat1));
+}
+
+void tst_QAudioFormat::checkAssignment()
+{
+ QAudioFormat audioFormat0;
+ QAudioFormat audioFormat1;
+
+ audioFormat0.setFrequency(8000);
+ audioFormat0.setChannels(1);
+ audioFormat0.setSampleSize(8);
+ audioFormat0.setCodec("audio/pcm");
+ audioFormat0.setByteOrder(QAudioFormat::LittleEndian);
+ audioFormat0.setSampleType(QAudioFormat::UnSignedInt);
+
+ audioFormat1 = audioFormat0;
+ QVERIFY(audioFormat1 == audioFormat0);
+
+ QAudioFormat audioFormat2(audioFormat0);
+ QVERIFY(audioFormat2 == audioFormat0);
+}
+
+QTEST_MAIN(tst_QAudioFormat)
+
+#include "tst_qaudioformat.moc"
diff --git a/tests/auto/qaudioinput/qaudioinput.pro b/tests/auto/qaudioinput/qaudioinput.pro
new file mode 100644
index 000000000..96aca17c7
--- /dev/null
+++ b/tests/auto/qaudioinput/qaudioinput.pro
@@ -0,0 +1,18 @@
+load(qttest_p4)
+
+QT += core multimediakit-private
+
+# TARGET = tst_qaudioinput
+# CONFIG += testcase
+
+wince*{
+ DEFINES += SRCDIR=\\\"\\\"
+ QT += gui
+} else {
+ !symbian:DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
+HEADERS += wavheader.h
+SOURCES += wavheader.cpp tst_qaudioinput.cpp
+
+maemo*:CONFIG += insignificant_test
diff --git a/tests/auto/qaudioinput/tst_qaudioinput.cpp b/tests/auto/qaudioinput/tst_qaudioinput.cpp
new file mode 100755
index 000000000..fb5f2e229
--- /dev/null
+++ b/tests/auto/qaudioinput/tst_qaudioinput.cpp
@@ -0,0 +1,814 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtCore/qlocale.h>
+
+#include <qaudioinput.h>
+#include <qaudiodeviceinfo.h>
+#include <qaudioformat.h>
+#include <qaudio.h>
+
+#include "wavheader.h"
+
+//TESTED_COMPONENT=src/multimedia
+
+#define AUDIO_BUFFER 192000
+
+#if defined(Q_OS_SYMBIAN)
+#define SRCDIR ""
+#endif
+
+#ifndef QTRY_VERIFY2
+#define QTRY_VERIFY2(__expr,__msg) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 5000; \
+ if (!(__expr)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ QVERIFY2(__expr,__msg); \
+ } while(0)
+#endif
+
+Q_DECLARE_METATYPE(QAudioFormat)
+
+class tst_QAudioInput : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QAudioInput(QObject* parent=0) : QObject(parent) {}
+
+private slots:
+ void initTestCase();
+
+ void format();
+ void invalidFormat_data();
+ void invalidFormat();
+
+ void bufferSize();
+
+ void notifyInterval();
+ void disableNotifyInterval();
+
+ void stopWhileStopped();
+ void suspendWhileStopped();
+ void resumeWhileStopped();
+
+ void pull();
+ void pullSuspendResume();
+
+ void push();
+ void pushSuspendResume();
+
+ void reset();
+
+ void cleanupTestCase();
+
+private:
+ QString formatToFileName(const QAudioFormat &format);
+ QString workingDir();
+
+ QAudioDeviceInfo audioDevice;
+ QList<QAudioFormat> testFormats;
+ QList<QFile*> audioFiles;
+
+ QScopedPointer<QByteArray> m_byteArray;
+ QScopedPointer<QBuffer> m_buffer;
+};
+
+QString tst_QAudioInput::formatToFileName(const QAudioFormat &format)
+{
+ const QString formatEndian = (format.byteOrder() == QAudioFormat::LittleEndian)
+ ? QString("LE") : QString("BE");
+
+ const QString formatSigned = (format.sampleType() == QAudioFormat::SignedInt)
+ ? QString("signed") : QString("unsigned");
+
+ return QString("%1_%2_%3_%4_%5")
+ .arg(format.frequency())
+ .arg(format.sampleSize())
+ .arg(formatSigned)
+ .arg(formatEndian)
+ .arg(format.channels());
+}
+
+
+QString tst_QAudioInput::workingDir()
+{
+ QDir working(QString(SRCDIR));
+
+ if (working.exists())
+ return QString(SRCDIR);
+
+ return QDir::currentPath();
+}
+
+void tst_QAudioInput::initTestCase()
+{
+ qRegisterMetaType<QAudioFormat>();
+
+ // Only perform tests if audio output device exists
+ const QList<QAudioDeviceInfo> devices =
+ QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
+
+ if (devices.size() <= 0)
+ QSKIP("No audio backend", SkipAll);
+
+ audioDevice = QAudioDeviceInfo::defaultInputDevice();
+
+
+ QAudioFormat format;
+
+ format.setCodec("audio/pcm");
+
+ if (audioDevice.isFormatSupported(audioDevice.preferredFormat()))
+ testFormats.append(audioDevice.preferredFormat());
+
+ // PCM 8000 mono S8
+ format.setFrequency(8000);
+ format.setSampleSize(8);
+ format.setSampleType(QAudioFormat::SignedInt);
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setChannels(1);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 11025 mono S16LE
+ format.setFrequency(11025);
+ format.setSampleSize(16);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 22050 mono S16LE
+ format.setFrequency(22050);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 22050 stereo S16LE
+ format.setChannels(2);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 44100 stereo S16LE
+ format.setFrequency(44100);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 48000 stereo S16LE
+ format.setFrequency(48000);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ QVERIFY(testFormats.size());
+
+ foreach (format, testFormats) {
+ QFile* file = new QFile(workingDir() + formatToFileName(format) + QString(".wav"));
+ audioFiles.append(file);
+ }
+}
+
+void tst_QAudioInput::format()
+{
+ QAudioInput audioInput(audioDevice.preferredFormat(), this);
+
+ QAudioFormat requested = audioDevice.preferredFormat();
+ QAudioFormat actual = audioInput.format();
+
+ QVERIFY2((requested.channels() == actual.channels()),
+ QString("channels: requested=%1, actual=%2").arg(requested.channels()).arg(actual.channels()).toLocal8Bit().constData());
+ QVERIFY2((requested.frequency() == actual.frequency()),
+ QString("frequency: requested=%1, actual=%2").arg(requested.frequency()).arg(actual.frequency()).toLocal8Bit().constData());
+ QVERIFY2((requested.sampleSize() == actual.sampleSize()),
+ QString("sampleSize: requested=%1, actual=%2").arg(requested.sampleSize()).arg(actual.sampleSize()).toLocal8Bit().constData());
+ QVERIFY2((requested.codec() == actual.codec()),
+ QString("codec: requested=%1, actual=%2").arg(requested.codec()).arg(actual.codec()).toLocal8Bit().constData());
+ QVERIFY2((requested.byteOrder() == actual.byteOrder()),
+ QString("byteOrder: requested=%1, actual=%2").arg(requested.byteOrder()).arg(actual.byteOrder()).toLocal8Bit().constData());
+ QVERIFY2((requested.sampleType() == actual.sampleType()),
+ QString("sampleType: requested=%1, actual=%2").arg(requested.sampleType()).arg(actual.sampleType()).toLocal8Bit().constData());
+}
+
+void tst_QAudioInput::invalidFormat_data()
+{
+ QTest::addColumn<QAudioFormat>("invalidFormat");
+
+ QAudioFormat format;
+
+ QTest::newRow("Null Format")
+ << format;
+
+ format = audioDevice.preferredFormat();
+ format.setChannelCount(0);
+ QTest::newRow("Channel count 0")
+ << format;
+
+ format = audioDevice.preferredFormat();
+ format.setSampleRate(0);
+ QTest::newRow("Sample rate 0")
+ << format;
+
+ format = audioDevice.preferredFormat();
+ format.setSampleSize(0);
+ QTest::newRow("Sample size 0")
+ << format;
+}
+
+void tst_QAudioInput::invalidFormat()
+{
+ QFETCH(QAudioFormat, invalidFormat);
+
+ QVERIFY2(!audioDevice.isFormatSupported(invalidFormat),
+ "isFormatSupported() is returning true on an invalid format");
+
+ QAudioInput audioInput(invalidFormat, this);
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+
+ audioInput.start();
+ // Check that error is raised
+ QTRY_VERIFY2((audioInput.error() == QAudio::OpenError),"error() was not set to QAudio::OpenError after start()");
+}
+
+void tst_QAudioInput::bufferSize()
+{
+ QAudioInput audioInput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");
+
+ audioInput.setBufferSize(512);
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(512)");
+ QVERIFY2((audioInput.bufferSize() == 512),
+ QString("bufferSize: requested=512, actual=%2").arg(audioInput.bufferSize()).toLocal8Bit().constData());
+
+ audioInput.setBufferSize(4096);
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(4096)");
+ QVERIFY2((audioInput.bufferSize() == 4096),
+ QString("bufferSize: requested=4096, actual=%2").arg(audioInput.bufferSize()).toLocal8Bit().constData());
+
+ audioInput.setBufferSize(8192);
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(8192)");
+ QVERIFY2((audioInput.bufferSize() == 8192),
+ QString("bufferSize: requested=8192, actual=%2").arg(audioInput.bufferSize()).toLocal8Bit().constData());
+}
+
+void tst_QAudioInput::notifyInterval()
+{
+ QAudioInput audioInput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");
+
+ audioInput.setNotifyInterval(50);
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(50)");
+ QVERIFY2((audioInput.notifyInterval() == 50),
+ QString("notifyInterval: requested=50, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());
+
+ audioInput.setNotifyInterval(100);
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(100)");
+ QVERIFY2((audioInput.notifyInterval() == 100),
+ QString("notifyInterval: requested=100, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());
+
+ audioInput.setNotifyInterval(250);
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(250)");
+ QVERIFY2((audioInput.notifyInterval() == 250),
+ QString("notifyInterval: requested=250, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());
+
+ audioInput.setNotifyInterval(1000);
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(1000)");
+ QVERIFY2((audioInput.notifyInterval() == 1000),
+ QString("notifyInterval: requested=1000, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());
+}
+
+void tst_QAudioInput::disableNotifyInterval()
+{
+ // Sets an invalid notification interval (QAudioInput::setNotifyInterval(0))
+ // Checks that
+ // - No error is raised (QAudioInput::error() returns QAudio::NoError)
+ // - if <= 0, set to zero and disable notify signal
+
+ QAudioInput audioInput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");
+
+ audioInput.setNotifyInterval(0);
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(0)");
+ QVERIFY2((audioInput.notifyInterval() == 0),
+ "notifyInterval() is not zero after setNotifyInterval(0)");
+
+ audioInput.setNotifyInterval(-1);
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(-1)");
+ QVERIFY2((audioInput.notifyInterval() == 0),
+ "notifyInterval() is not zero after setNotifyInterval(-1)");
+
+ //start and run to check if notify() is emitted
+ if (audioFiles.size() > 0) {
+ QAudioInput audioInputCheck(testFormats.at(0), this);
+ audioInputCheck.setNotifyInterval(0);
+ QSignalSpy notifySignal(&audioInputCheck, SIGNAL(notify()));
+ audioFiles.at(0)->open(QIODevice::WriteOnly);
+ audioInputCheck.start(audioFiles.at(0));
+ QTest::qWait(3000); // 3 seconds should be plenty
+ audioInputCheck.stop();
+ QVERIFY2((notifySignal.count() == 0),
+ QString("didn't disable notify interval: shouldn't have got any but got %1").arg(notifySignal.count()).toLocal8Bit().constData());
+ audioFiles.at(0)->close();
+ }
+}
+
+void tst_QAudioInput::stopWhileStopped()
+{
+ // Calls QAudioInput::stop() when object is already in StoppedState
+ // Checks that
+ // - No state change occurs
+ // - No error is raised (QAudioInput::error() returns QAudio::NoError)
+
+ QAudioInput audioInput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+
+ QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
+ audioInput.stop();
+
+ // Check that no state transition occurred
+ QVERIFY2((stateSignal.count() == 0), "stop() while stopped is emitting a signal and it shouldn't");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after stop()");
+}
+
+void tst_QAudioInput::suspendWhileStopped()
+{
+ // Calls QAudioInput::suspend() when object is already in StoppedState
+ // Checks that
+ // - No state change occurs
+ // - No error is raised (QAudioInput::error() returns QAudio::NoError)
+
+ QAudioInput audioInput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+
+ QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
+ audioInput.suspend();
+
+ // Check that no state transition occurred
+ QVERIFY2((stateSignal.count() == 0), "stop() while suspended is emitting a signal and it shouldn't");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after stop()");
+}
+
+void tst_QAudioInput::resumeWhileStopped()
+{
+ // Calls QAudioInput::resume() when object is already in StoppedState
+ // Checks that
+ // - No state change occurs
+ // - No error is raised (QAudioInput::error() returns QAudio::NoError)
+
+ QAudioInput audioInput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+
+ QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
+ audioInput.resume();
+
+ // Check that no state transition occurred
+ QVERIFY2((stateSignal.count() == 0), "resume() while stopped is emitting a signal and it shouldn't");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after resume()");
+}
+
+void tst_QAudioInput::pull()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioInput audioInput(testFormats.at(i), this);
+
+ audioInput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioInput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioFiles.at(i)->close();
+ audioFiles.at(i)->open(QIODevice::WriteOnly);
+ WavHeader wavHeader(testFormats.at(i));
+ QVERIFY(wavHeader.write(*audioFiles.at(i)));
+
+ audioInput.start(audioFiles.at(i));
+ // Check that QAudioInput immediately transitions to ActiveState or IdleState
+ QTRY_VERIFY2((stateSignal.count() > 0),"didn't emit signals on start()");
+ QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState),
+ "didn't transition to ActiveState or IdleState after start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioInput.periodSize() > 0);
+ stateSignal.clear();
+
+ // Check that 'elapsed' increases
+ QTest::qWait(40);
+ QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
+
+ // Allow some recording to happen
+ QTest::qWait(3000); // 3 seconds should be plenty
+
+ stateSignal.clear();
+
+ qint64 processedUs = audioInput.processedUSecs();
+
+ audioInput.stop();
+ QTest::qWait(40);
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
+
+ QVERIFY2((processedUs > 2800000 && processedUs < 3200000),
+ QString("processedUSecs() doesn't fall in acceptable range, should be 3040000 (%1)").arg(processedUs).toLocal8Bit().constData());
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
+ QVERIFY2((notifySignal.count() > 20 && notifySignal.count() < 40),
+ QString("notify() signals emitted (%1) should be 30").arg(notifySignal.count()).toLocal8Bit().constData());
+
+ WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength());
+ audioFiles.at(i)->close();
+ }
+}
+
+void tst_QAudioInput::pullSuspendResume()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioInput audioInput(testFormats.at(i), this);
+
+ audioInput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioInput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioFiles.at(i)->close();
+ audioFiles.at(i)->open(QIODevice::WriteOnly);
+ WavHeader wavHeader(testFormats.at(i));
+ QVERIFY(wavHeader.write(*audioFiles.at(i)));
+
+ audioInput.start(audioFiles.at(i));
+ // Check that QAudioInput immediately transitions to ActiveState or IdleState
+ QTRY_VERIFY2((stateSignal.count() > 0),"didn't emit signals on start()");
+ QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState),
+ "didn't transition to ActiveState or IdleState after start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioInput.periodSize() > 0);
+ stateSignal.clear();
+
+ // Check that 'elapsed' increases
+ QTest::qWait(40);
+ QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
+
+ // Allow some recording to happen
+ QTest::qWait(3000); // 3 seconds should be plenty
+
+ QVERIFY2((audioInput.state() == QAudio::ActiveState),
+ "didn't transition to ActiveState after some recording");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after some recording");
+
+ stateSignal.clear();
+
+ audioInput.suspend();
+
+ // Give backends running in separate threads a chance to suspend.
+ QTest::qWait(100);
+
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioInput.state() == QAudio::SuspendedState), "didn't transitions to SuspendedState after stop()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ stateSignal.clear();
+
+ // Check that only 'elapsed', and not 'processed' increases while suspended
+ qint64 elapsedUs = audioInput.elapsedUSecs();
+ qint64 processedUs = audioInput.processedUSecs();
+ QTest::qWait(1000);
+ QVERIFY(audioInput.elapsedUSecs() > elapsedUs);
+ QVERIFY(audioInput.processedUSecs() == processedUs);
+
+ audioInput.resume();
+
+ // Give backends running in separate threads a chance to resume.
+ QTest::qWait(100);
+
+ // Check that QAudioInput immediately transitions to ActiveState
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal after resume(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioInput.state() == QAudio::ActiveState), "didn't transition to ActiveState after resume()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()");
+ stateSignal.clear();
+
+ processedUs = audioInput.processedUSecs();
+
+ audioInput.stop();
+ QTest::qWait(40);
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
+
+ QVERIFY2((processedUs > 2800000 && processedUs < 3200000),
+ QString("processedUSecs() doesn't fall in acceptable range, should be 3040000 (%1)").arg(processedUs).toLocal8Bit().constData());
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
+ QVERIFY2((notifySignal.count() > 20 && notifySignal.count() < 40),
+ QString("notify() signals emitted (%1) should be 30").arg(notifySignal.count()).toLocal8Bit().constData());
+
+ WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength());
+ audioFiles.at(i)->close();
+ }
+}
+
+void tst_QAudioInput::push()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioInput audioInput(testFormats.at(i), this);
+
+ audioInput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioInput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioFiles.at(i)->close();
+ audioFiles.at(i)->open(QIODevice::WriteOnly);
+ WavHeader wavHeader(testFormats.at(i));
+ QVERIFY(wavHeader.write(*audioFiles.at(i)));
+
+ QIODevice* feed = audioInput.start();
+
+ // Check that QAudioInput immediately transitions to IdleState
+ QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit IdleState signal on start()");
+ QVERIFY2((audioInput.state() == QAudio::IdleState),
+ "didn't transition to IdleState after start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioInput.periodSize() > 0);
+ stateSignal.clear();
+
+ // Check that 'elapsed' increases
+ QTest::qWait(40);
+ QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
+
+ qint64 totalBytesRead = 0;
+ bool firstBuffer = true;
+ QByteArray buffer(AUDIO_BUFFER, 0);
+ qint64 len = (testFormats.at(i).frequency()*testFormats.at(i).channels()*(testFormats.at(i).sampleSize()/8)*2); // 2 seconds
+ while (totalBytesRead < len) {
+ if (audioInput.bytesReady() >= audioInput.periodSize()) {
+ qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize());
+ audioFiles.at(i)->write(buffer.constData(),bytesRead);
+ totalBytesRead+=bytesRead;
+ if (firstBuffer && bytesRead) {
+ // Check for transition to ActiveState when data is provided
+ QVERIFY2((stateSignal.count() == 1),"didn't emit ActiveState signal on data");
+ QVERIFY2((audioInput.state() == QAudio::ActiveState),
+ "didn't transition to ActiveState after data");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ firstBuffer = false;
+ }
+ } else
+ QTest::qWait(20);
+ }
+
+ QTest::qWait(1000);
+
+ stateSignal.clear();
+
+ qint64 processedUs = audioInput.processedUSecs();
+
+ audioInput.stop();
+ QTest::qWait(40);
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
+
+ QVERIFY2((processedUs > 1800000 && processedUs < 2200000),
+ QString("processedUSecs() doesn't fall in acceptable range, should be 2040000 (%1)").arg(processedUs).toLocal8Bit().constData());
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
+ QVERIFY2((notifySignal.count() > 20 && notifySignal.count() < 40),
+ QString("notify() signals emitted (%1) should be 30").arg(notifySignal.count()).toLocal8Bit().constData());
+
+ WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength());
+ audioFiles.at(i)->close();
+ }
+}
+
+void tst_QAudioInput::pushSuspendResume()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioInput audioInput(testFormats.at(i), this);
+
+ audioInput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioInput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioFiles.at(i)->close();
+ audioFiles.at(i)->open(QIODevice::WriteOnly);
+ WavHeader wavHeader(testFormats.at(i));
+ QVERIFY(wavHeader.write(*audioFiles.at(i)));
+
+ QIODevice* feed = audioInput.start();
+
+ // Check that QAudioInput immediately transitions to IdleState
+ QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit IdleState signal on start()");
+ QVERIFY2((audioInput.state() == QAudio::IdleState),
+ "didn't transition to IdleState after start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioInput.periodSize() > 0);
+ stateSignal.clear();
+
+ // Check that 'elapsed' increases
+ QTest::qWait(40);
+ QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
+
+ qint64 totalBytesRead = 0;
+ bool firstBuffer = true;
+ QByteArray buffer(AUDIO_BUFFER, 0);
+ qint64 len = (testFormats.at(i).frequency()*testFormats.at(i).channels()*(testFormats.at(i).sampleSize()/8)); // 1 seconds
+ while (totalBytesRead < len) {
+ if (audioInput.bytesReady() >= audioInput.periodSize()) {
+ qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize());
+ audioFiles.at(i)->write(buffer.constData(),bytesRead);
+ totalBytesRead+=bytesRead;
+ if (firstBuffer && bytesRead) {
+ // Check for transition to ActiveState when data is provided
+ QVERIFY2((stateSignal.count() == 1),"didn't emit ActiveState signal on data");
+ QVERIFY2((audioInput.state() == QAudio::ActiveState),
+ "didn't transition to ActiveState after data");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ firstBuffer = false;
+ }
+ } else
+ QTest::qWait(20);
+ }
+ stateSignal.clear();
+
+ audioInput.suspend();
+
+ // Give backends running in separate threads a chance to suspend
+ QTest::qWait(100);
+
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioInput.state() == QAudio::SuspendedState), "didn't transitions to SuspendedState after stop()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ stateSignal.clear();
+
+ // Check that only 'elapsed', and not 'processed' increases while suspended
+ qint64 elapsedUs = audioInput.elapsedUSecs();
+ qint64 processedUs = audioInput.processedUSecs();
+ QTest::qWait(1000);
+ QVERIFY(audioInput.elapsedUSecs() > elapsedUs);
+ QVERIFY(audioInput.processedUSecs() == processedUs);
+
+ audioInput.resume();
+
+ // Give backends running in separate threads a chance to resume.
+ QTest::qWait(100);
+
+ // Check that QAudioInput immediately transitions to Active or IdleState
+ QVERIFY2((stateSignal.count() > 0),"didn't emit signals on resume()");
+ QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState),
+ "didn't transition to ActiveState or IdleState after resume()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()");
+ QVERIFY(audioInput.periodSize() > 0);
+
+ // Let it play out what is in buffer and go to Idle before continue
+ QTest::qWait(1000);
+ stateSignal.clear();
+
+ // Read another seconds worth
+ totalBytesRead = 0;
+ firstBuffer = true;
+ while (totalBytesRead < len) {
+ if (audioInput.bytesReady() >= audioInput.periodSize()) {
+ qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize());
+ audioFiles.at(i)->write(buffer.constData(),bytesRead);
+ totalBytesRead+=bytesRead;
+ } else
+ QTest::qWait(20);
+ }
+ stateSignal.clear();
+
+ processedUs = audioInput.processedUSecs();
+
+ audioInput.stop();
+ QTest::qWait(40);
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
+
+ QVERIFY2((processedUs > 1800000 && processedUs < 2200000),
+ QString("processedUSecs() doesn't fall in acceptable range, should be 2040000 (%1)").arg(processedUs).toLocal8Bit().constData());
+ QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
+
+ WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength());
+ audioFiles.at(i)->close();
+ }
+}
+
+void tst_QAudioInput::reset()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioInput audioInput(testFormats.at(i), this);
+
+ audioInput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioInput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioInput.start();
+ // Check that QAudioInput immediately transitions to IdleState
+ QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit IdleState signal on start()");
+ QVERIFY2((audioInput.state() == QAudio::IdleState), "didn't transition to IdleState after start()");
+ QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioInput.periodSize() > 0);
+ QTest::qWait(500);
+ QVERIFY(audioInput.bytesReady() > 0);
+ stateSignal.clear();
+
+ audioInput.reset();
+ QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit StoppedState signal after reset()");
+ QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after reset()");
+ QVERIFY2((audioInput.bytesReady() == 0), "buffer not cleared after reset()");
+ }
+}
+
+void tst_QAudioInput::cleanupTestCase()
+{
+ QFile* file;
+
+ foreach (file, audioFiles) {
+ file->remove();
+ delete file;
+ }
+}
+
+QTEST_MAIN(tst_QAudioInput)
+
+#include "tst_qaudioinput.moc"
diff --git a/tests/auto/qaudioinput/wavheader.cpp b/tests/auto/qaudioinput/wavheader.cpp
new file mode 100755
index 000000000..26fcd6f98
--- /dev/null
+++ b/tests/auto/qaudioinput/wavheader.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qendian.h>
+#include "wavheader.h"
+
+
+struct chunk
+{
+ char id[4];
+ quint32 size;
+};
+
+struct RIFFHeader
+{
+ chunk descriptor; // "RIFF"
+ char type[4]; // "WAVE"
+};
+
+struct WAVEHeader
+{
+ chunk descriptor;
+ quint16 audioFormat;
+ quint16 numChannels;
+ quint32 sampleRate;
+ quint32 byteRate;
+ quint16 blockAlign;
+ quint16 bitsPerSample;
+};
+
+struct DATAHeader
+{
+ chunk descriptor;
+};
+
+struct CombinedHeader
+{
+ RIFFHeader riff;
+ WAVEHeader wave;
+ DATAHeader data;
+};
+
+static const int HeaderLength = sizeof(CombinedHeader);
+
+
+WavHeader::WavHeader(const QAudioFormat &format, qint64 dataLength)
+ : m_format(format)
+ , m_dataLength(dataLength)
+{
+
+}
+
+bool WavHeader::read(QIODevice &device)
+{
+ bool result = true;
+
+ if (!device.isSequential())
+ result = device.seek(0);
+ // else, assume that current position is the start of the header
+
+ if (result) {
+ CombinedHeader header;
+ result = (device.read(reinterpret_cast<char *>(&header), HeaderLength) == HeaderLength);
+ if (result) {
+ if ((memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0
+ || memcmp(&header.riff.descriptor.id, "RIFX", 4) == 0)
+ && memcmp(&header.riff.type, "WAVE", 4) == 0
+ && memcmp(&header.wave.descriptor.id, "fmt ", 4) == 0
+ && header.wave.audioFormat == 1 // PCM
+ ) {
+ if (memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0)
+ m_format.setByteOrder(QAudioFormat::LittleEndian);
+ else
+ m_format.setByteOrder(QAudioFormat::BigEndian);
+
+ m_format.setChannels(qFromLittleEndian<quint16>(header.wave.numChannels));
+ m_format.setCodec("audio/pcm");
+ m_format.setFrequency(qFromLittleEndian<quint32>(header.wave.sampleRate));
+ m_format.setSampleSize(qFromLittleEndian<quint16>(header.wave.bitsPerSample));
+
+ switch(header.wave.bitsPerSample) {
+ case 8:
+ m_format.setSampleType(QAudioFormat::UnSignedInt);
+ break;
+ case 16:
+ m_format.setSampleType(QAudioFormat::SignedInt);
+ break;
+ default:
+ result = false;
+ }
+
+ m_dataLength = device.size() - HeaderLength;
+ } else {
+ result = false;
+ }
+ }
+ }
+
+ return result;
+}
+
+bool WavHeader::write(QIODevice &device)
+{
+ CombinedHeader header;
+
+ memset(&header, 0, HeaderLength);
+
+ // RIFF header
+ if (m_format.byteOrder() == QAudioFormat::LittleEndian)
+ memcpy(header.riff.descriptor.id,"RIFF",4);
+ else
+ memcpy(header.riff.descriptor.id,"RIFX",4);
+ qToLittleEndian<quint32>(quint32(m_dataLength + HeaderLength - 8),
+ reinterpret_cast<unsigned char*>(&header.riff.descriptor.size));
+ memcpy(header.riff.type, "WAVE",4);
+
+ // WAVE header
+ memcpy(header.wave.descriptor.id,"fmt ",4);
+ qToLittleEndian<quint32>(quint32(16),
+ reinterpret_cast<unsigned char*>(&header.wave.descriptor.size));
+ qToLittleEndian<quint16>(quint16(1),
+ reinterpret_cast<unsigned char*>(&header.wave.audioFormat));
+ qToLittleEndian<quint16>(quint16(m_format.channels()),
+ reinterpret_cast<unsigned char*>(&header.wave.numChannels));
+ qToLittleEndian<quint32>(quint32(m_format.frequency()),
+ reinterpret_cast<unsigned char*>(&header.wave.sampleRate));
+ qToLittleEndian<quint32>(quint32(m_format.frequency() * m_format.channels() * m_format.sampleSize() / 8),
+ reinterpret_cast<unsigned char*>(&header.wave.byteRate));
+ qToLittleEndian<quint16>(quint16(m_format.channels() * m_format.sampleSize() / 8),
+ reinterpret_cast<unsigned char*>(&header.wave.blockAlign));
+ qToLittleEndian<quint16>(quint16(m_format.sampleSize()),
+ reinterpret_cast<unsigned char*>(&header.wave.bitsPerSample));
+
+ // DATA header
+ memcpy(header.data.descriptor.id,"data",4);
+ qToLittleEndian<quint32>(quint32(m_dataLength),
+ reinterpret_cast<unsigned char*>(&header.data.descriptor.size));
+
+ return (device.write(reinterpret_cast<const char *>(&header), HeaderLength) == HeaderLength);
+}
+
+const QAudioFormat& WavHeader::format() const
+{
+ return m_format;
+}
+
+qint64 WavHeader::dataLength() const
+{
+ return m_dataLength;
+}
+
+qint64 WavHeader::headerLength()
+{
+ return HeaderLength;
+}
+
+bool WavHeader::writeDataLength(QIODevice &device, qint64 dataLength)
+{
+ bool result = false;
+ if (!device.isSequential()) {
+ device.seek(40);
+ unsigned char dataLengthLE[4];
+ qToLittleEndian<quint32>(quint32(dataLength), dataLengthLE);
+ result = (device.write(reinterpret_cast<const char *>(dataLengthLE), 4) == 4);
+ }
+ return result;
+}
diff --git a/tests/auto/qaudioinput/wavheader.h b/tests/auto/qaudioinput/wavheader.h
new file mode 100755
index 000000000..4136da027
--- /dev/null
+++ b/tests/auto/qaudioinput/wavheader.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef WAVHEADER_H
+#define WAVHEADER_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qfile.h>
+#include <qaudioformat.h>
+
+/**
+ * Helper class for parsing WAV file headers.
+ *
+ * See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
+ */
+class WavHeader
+{
+public:
+ WavHeader(const QAudioFormat &format = QAudioFormat(),
+ qint64 dataLength = 0);
+
+ // Reads WAV header and seeks to start of data
+ bool read(QIODevice &device);
+
+ // Writes WAV header
+ bool write(QIODevice &device);
+
+ const QAudioFormat& format() const;
+ qint64 dataLength() const;
+
+ static qint64 headerLength();
+
+ static bool writeDataLength(QIODevice &device, qint64 dataLength);
+
+private:
+ QAudioFormat m_format;
+ qint64 m_dataLength;
+};
+
+#endif
+
diff --git a/tests/auto/qaudiooutput/qaudiooutput.pro b/tests/auto/qaudiooutput/qaudiooutput.pro
new file mode 100644
index 000000000..b99128c77
--- /dev/null
+++ b/tests/auto/qaudiooutput/qaudiooutput.pro
@@ -0,0 +1,18 @@
+load(qttest_p4)
+
+QT += core multimediakit-private
+
+# TARGET = tst_qaudiooutput
+# CONFIG += testcase
+
+wince*: {
+ DEFINES += SRCDIR=\\\"\\\"
+ QT += gui
+} else {
+ !symbian:DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
+HEADERS += wavheader.h
+SOURCES += wavheader.cpp tst_qaudiooutput.cpp
+
+maemo*:CONFIG += insignificant_test
diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp
new file mode 100755
index 000000000..2590af39d
--- /dev/null
+++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp
@@ -0,0 +1,962 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include <QtTest/QtTest>
+#include <QtCore/qlocale.h>
+
+#include <qaudiooutput.h>
+#include <qaudiodeviceinfo.h>
+#include <qaudioformat.h>
+#include <qaudio.h>
+
+#include "wavheader.h"
+
+#define AUDIO_BUFFER 192000
+
+#if defined(Q_OS_SYMBIAN)
+#define SRCDIR ""
+#endif
+
+#ifndef QTRY_VERIFY2
+#define QTRY_VERIFY2(__expr,__msg) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 5000; \
+ if (!(__expr)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ QVERIFY2(__expr,__msg); \
+ } while(0)
+#endif
+
+Q_DECLARE_METATYPE(QAudioFormat)
+
+class tst_QAudioOutput : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QAudioOutput(QObject* parent=0) : QObject(parent) {}
+
+private slots:
+ void initTestCase();
+
+ void format();
+ void invalidFormat_data();
+ void invalidFormat();
+
+ void bufferSize();
+
+ void notifyInterval();
+ void disableNotifyInterval();
+
+ void stopWhileStopped();
+ void suspendWhileStopped();
+ void resumeWhileStopped();
+
+ void pull();
+ void pullSuspendResume();
+
+ void push();
+ void pushSuspendResume();
+ void pushUnderrun();
+
+ void cleanupTestCase();
+
+private:
+ QString formatToFileName(const QAudioFormat &format);
+ QString workingDir();
+ void createSineWaveData(const QAudioFormat &format, qint64 length, int frequency = 440);
+
+ QAudioDeviceInfo audioDevice;
+ QList<QAudioFormat> testFormats;
+ QList<QFile*> audioFiles;
+
+ QScopedPointer<QByteArray> m_byteArray;
+ QScopedPointer<QBuffer> m_buffer;
+};
+
+QString tst_QAudioOutput::formatToFileName(const QAudioFormat &format)
+{
+ const QString formatEndian = (format.byteOrder() == QAudioFormat::LittleEndian)
+ ? QString("LE") : QString("BE");
+
+ const QString formatSigned = (format.sampleType() == QAudioFormat::SignedInt)
+ ? QString("signed") : QString("unsigned");
+
+ return QString("%1_%2_%3_%4_%5")
+ .arg(format.frequency())
+ .arg(format.sampleSize())
+ .arg(formatSigned)
+ .arg(formatEndian)
+ .arg(format.channels());
+}
+
+
+QString tst_QAudioOutput::workingDir()
+{
+ QDir working(QString(SRCDIR));
+
+ if (working.exists())
+ return QString(SRCDIR);
+
+ return QDir::currentPath();
+}
+
+void tst_QAudioOutput::createSineWaveData(const QAudioFormat &format, qint64 length, int frequency)
+{
+ const int channelBytes = format.sampleSize() / 8;
+ const int sampleBytes = format.channels() * channelBytes;
+
+ Q_ASSERT(length % sampleBytes == 0);
+ Q_UNUSED(sampleBytes) // suppress warning in release builds
+
+ m_byteArray.reset(new QByteArray(length, 0));
+ unsigned char *ptr = reinterpret_cast<unsigned char *>(m_byteArray->data());
+ int sampleIndex = 0;
+
+ while (length) {
+ const qreal x = qSin(2 * M_PI * frequency * qreal(sampleIndex % format.frequency()) / format.frequency());
+ for (int i=0; i<format.channels(); ++i) {
+ if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) {
+ const quint8 value = static_cast<quint8>((1.0 + x) / 2 * 255);
+ *reinterpret_cast<quint8*>(ptr) = value;
+ } else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) {
+ const qint8 value = static_cast<qint8>(x * 127);
+ *reinterpret_cast<quint8*>(ptr) = value;
+ } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) {
+ quint16 value = static_cast<quint16>((1.0 + x) / 2 * 65535);
+ if (format.byteOrder() == QAudioFormat::LittleEndian)
+ qToLittleEndian<quint16>(value, ptr);
+ else
+ qToBigEndian<quint16>(value, ptr);
+ } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) {
+ qint16 value = static_cast<qint16>(x * 32767);
+ if (format.byteOrder() == QAudioFormat::LittleEndian)
+ qToLittleEndian<qint16>(value, ptr);
+ else
+ qToBigEndian<qint16>(value, ptr);
+ }
+
+ ptr += channelBytes;
+ length -= channelBytes;
+ }
+ ++sampleIndex;
+ }
+
+ m_buffer.reset(new QBuffer(m_byteArray.data(), this));
+ Q_ASSERT(m_buffer->open(QIODevice::ReadOnly));
+}
+
+void tst_QAudioOutput::initTestCase()
+{
+ qRegisterMetaType<QAudioFormat>();
+
+ // Only perform tests if audio output device exists
+ const QList<QAudioDeviceInfo> devices =
+ QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
+
+ if (devices.size() <= 0)
+ QSKIP("No audio backend", SkipAll);
+
+ audioDevice = QAudioDeviceInfo::defaultOutputDevice();
+
+
+ QAudioFormat format;
+
+ format.setCodec("audio/pcm");
+
+ if (audioDevice.isFormatSupported(audioDevice.preferredFormat()))
+ testFormats.append(audioDevice.preferredFormat());
+
+ // PCM 8000 mono S8
+ format.setFrequency(8000);
+ format.setSampleSize(8);
+ format.setSampleType(QAudioFormat::SignedInt);
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setChannels(1);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 11025 mono S16LE
+ format.setFrequency(11025);
+ format.setSampleSize(16);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 22050 mono S16LE
+ format.setFrequency(22050);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 22050 stereo S16LE
+ format.setChannels(2);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 44100 stereo S16LE
+ format.setFrequency(44100);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ // PCM 48000 stereo S16LE
+ format.setFrequency(48000);
+ if (audioDevice.isFormatSupported(format))
+ testFormats.append(format);
+
+ QVERIFY(testFormats.size());
+
+ foreach (format, testFormats) {
+ qint64 len = (format.frequency()*format.channels()*(format.sampleSize()/8)*2); // 2 seconds
+ createSineWaveData(format, len);
+ // Write generate sine wave data to file
+ QFile* file = new QFile(workingDir() + QString("generated") + formatToFileName(format) + QString(".wav"));
+ if (file->open(QIODevice::WriteOnly)) {
+ WavHeader wavHeader(format, len);
+ wavHeader.write(*file);
+ file->write(m_byteArray->data(), len);
+ file->close();
+ audioFiles.append(file);
+ }
+ }
+}
+
+void tst_QAudioOutput::format()
+{
+ QAudioOutput audioOutput(audioDevice.preferredFormat(), this);
+
+ QAudioFormat requested = audioDevice.preferredFormat();
+ QAudioFormat actual = audioOutput.format();
+
+ QVERIFY2((requested.channels() == actual.channels()),
+ QString("channels: requested=%1, actual=%2").arg(requested.channels()).arg(actual.channels()).toLocal8Bit().constData());
+ QVERIFY2((requested.frequency() == actual.frequency()),
+ QString("frequency: requested=%1, actual=%2").arg(requested.frequency()).arg(actual.frequency()).toLocal8Bit().constData());
+ QVERIFY2((requested.sampleSize() == actual.sampleSize()),
+ QString("sampleSize: requested=%1, actual=%2").arg(requested.sampleSize()).arg(actual.sampleSize()).toLocal8Bit().constData());
+ QVERIFY2((requested.codec() == actual.codec()),
+ QString("codec: requested=%1, actual=%2").arg(requested.codec()).arg(actual.codec()).toLocal8Bit().constData());
+ QVERIFY2((requested.byteOrder() == actual.byteOrder()),
+ QString("byteOrder: requested=%1, actual=%2").arg(requested.byteOrder()).arg(actual.byteOrder()).toLocal8Bit().constData());
+ QVERIFY2((requested.sampleType() == actual.sampleType()),
+ QString("sampleType: requested=%1, actual=%2").arg(requested.sampleType()).arg(actual.sampleType()).toLocal8Bit().constData());
+}
+
+void tst_QAudioOutput::invalidFormat_data()
+{
+ QTest::addColumn<QAudioFormat>("invalidFormat");
+
+ QAudioFormat format;
+
+ QTest::newRow("Null Format")
+ << format;
+
+ format = audioDevice.preferredFormat();
+ format.setChannelCount(0);
+ QTest::newRow("Channel count 0")
+ << format;
+
+ format = audioDevice.preferredFormat();
+ format.setSampleRate(0);
+ QTest::newRow("Sample rate 0")
+ << format;
+
+ format = audioDevice.preferredFormat();
+ format.setSampleSize(0);
+ QTest::newRow("Sample size 0")
+ << format;
+}
+
+void tst_QAudioOutput::invalidFormat()
+{
+ QFETCH(QAudioFormat, invalidFormat);
+
+ QVERIFY2(!audioDevice.isFormatSupported(invalidFormat),
+ "isFormatSupported() is returning true on an invalid format");
+
+ QAudioOutput audioOutput(invalidFormat, this);
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+
+ audioOutput.start();
+ // Check that error is raised
+ QTRY_VERIFY2((audioOutput.error() == QAudio::OpenError),"error() was not set to QAudio::OpenError after start()");
+}
+
+void tst_QAudioOutput::bufferSize()
+{
+ QAudioOutput audioOutput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");
+
+ audioOutput.setBufferSize(512);
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(512)");
+ QVERIFY2((audioOutput.bufferSize() == 512),
+ QString("bufferSize: requested=512, actual=%2").arg(audioOutput.bufferSize()).toLocal8Bit().constData());
+
+ audioOutput.setBufferSize(4096);
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(4096)");
+ QVERIFY2((audioOutput.bufferSize() == 4096),
+ QString("bufferSize: requested=4096, actual=%2").arg(audioOutput.bufferSize()).toLocal8Bit().constData());
+
+ audioOutput.setBufferSize(8192);
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(8192)");
+ QVERIFY2((audioOutput.bufferSize() == 8192),
+ QString("bufferSize: requested=8192, actual=%2").arg(audioOutput.bufferSize()).toLocal8Bit().constData());
+}
+
+void tst_QAudioOutput::notifyInterval()
+{
+ QAudioOutput audioOutput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");
+
+ audioOutput.setNotifyInterval(50);
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(50)");
+ QVERIFY2((audioOutput.notifyInterval() == 50),
+ QString("notifyInterval: requested=50, actual=%2").arg(audioOutput.notifyInterval()).toLocal8Bit().constData());
+
+ audioOutput.setNotifyInterval(100);
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(100)");
+ QVERIFY2((audioOutput.notifyInterval() == 100),
+ QString("notifyInterval: requested=100, actual=%2").arg(audioOutput.notifyInterval()).toLocal8Bit().constData());
+
+ audioOutput.setNotifyInterval(250);
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(250)");
+ QVERIFY2((audioOutput.notifyInterval() == 250),
+ QString("notifyInterval: requested=250, actual=%2").arg(audioOutput.notifyInterval()).toLocal8Bit().constData());
+
+ audioOutput.setNotifyInterval(1000);
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(1000)");
+ QVERIFY2((audioOutput.notifyInterval() == 1000),
+ QString("notifyInterval: requested=1000, actual=%2").arg(audioOutput.notifyInterval()).toLocal8Bit().constData());
+}
+
+void tst_QAudioOutput::disableNotifyInterval()
+{
+ // Sets an invalid notification interval (QAudioOutput::setNotifyInterval(0))
+ // Checks that
+ // - No error is raised (QAudioOutput::error() returns QAudio::NoError)
+ // - if <= 0, set to zero and disable notify signal
+
+ QAudioOutput audioOutput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");
+
+ audioOutput.setNotifyInterval(0);
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(0)");
+ QVERIFY2((audioOutput.notifyInterval() == 0),
+ "notifyInterval() is not zero after setNotifyInterval(0)");
+
+ audioOutput.setNotifyInterval(-1);
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(-1)");
+ QVERIFY2((audioOutput.notifyInterval() == 0),
+ "notifyInterval() is not zero after setNotifyInterval(-1)");
+
+ //start and run to check if notify() is emitted
+ if (audioFiles.size() > 0) {
+ QAudioOutput audioOutputCheck(testFormats.at(0), this);
+ audioOutputCheck.setNotifyInterval(0);
+ QSignalSpy notifySignal(&audioOutputCheck, SIGNAL(notify()));
+ audioFiles.at(0)->open(QIODevice::ReadOnly);
+ audioOutputCheck.start(audioFiles.at(0));
+ QTest::qWait(3000); // 3 seconds should be plenty
+ audioOutputCheck.stop();
+ QVERIFY2((notifySignal.count() == 0),
+ QString("didn't disable notify interval: shouldn't have got any but got %1").arg(notifySignal.count()).toLocal8Bit().constData());
+ audioFiles.at(0)->close();
+ }
+}
+
+void tst_QAudioOutput::stopWhileStopped()
+{
+ // Calls QAudioOutput::stop() when object is already in StoppedState
+ // Checks that
+ // - No state change occurs
+ // - No error is raised (QAudioOutput::error() returns QAudio::NoError)
+
+ QAudioOutput audioOutput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+
+ QSignalSpy stateSignal(&audioOutput, SIGNAL(stateChanged(QAudio::State)));
+ audioOutput.stop();
+
+ // Check that no state transition occurred
+ QVERIFY2((stateSignal.count() == 0), "stop() while stopped is emitting a signal and it shouldn't");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after stop()");
+}
+
+void tst_QAudioOutput::suspendWhileStopped()
+{
+ // Calls QAudioOutput::suspend() when object is already in StoppedState
+ // Checks that
+ // - No state change occurs
+ // - No error is raised (QAudioOutput::error() returns QAudio::NoError)
+
+ QAudioOutput audioOutput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+
+ QSignalSpy stateSignal(&audioOutput, SIGNAL(stateChanged(QAudio::State)));
+ audioOutput.suspend();
+
+ // Check that no state transition occurred
+ QVERIFY2((stateSignal.count() == 0), "stop() while suspended is emitting a signal and it shouldn't");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after stop()");
+}
+
+void tst_QAudioOutput::resumeWhileStopped()
+{
+ // Calls QAudioOutput::resume() when object is already in StoppedState
+ // Checks that
+ // - No state change occurs
+ // - No error is raised (QAudioOutput::error() returns QAudio::NoError)
+
+ QAudioOutput audioOutput(audioDevice.preferredFormat(), this);
+
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+
+ QSignalSpy stateSignal(&audioOutput, SIGNAL(stateChanged(QAudio::State)));
+ audioOutput.resume();
+
+ // Check that no state transition occurred
+ QVERIFY2((stateSignal.count() == 0), "resume() while stopped is emitting a signal and it shouldn't");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after resume()");
+}
+
+void tst_QAudioOutput::pull()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioOutput audioOutput(testFormats.at(i), this);
+
+ audioOutput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioOutput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioOutput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioOutput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioFiles.at(i)->close();
+ audioFiles.at(i)->open(QIODevice::ReadOnly);
+ audioFiles.at(i)->seek(WavHeader::headerLength());
+
+ audioOutput.start(audioFiles.at(i));
+ // Check that QAudioOutput immediately transitions to ActiveState
+ QTRY_VERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal on start(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::ActiveState), "didn't transition to ActiveState after start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioOutput.periodSize() > 0);
+ stateSignal.clear();
+
+ // Check that 'elapsed' increases
+ QTest::qWait(40);
+ QVERIFY2((audioOutput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
+
+ // Wait until playback finishes
+ QTest::qWait(3000); // 3 seconds should be plenty
+
+ QVERIFY2(audioFiles.at(i)->atEnd(), "didn't play to EOF");
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit IdleState signal when at EOF, got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transitions to IdleState when at EOF");
+ stateSignal.clear();
+
+ qint64 processedUs = audioOutput.processedUSecs();
+
+ audioOutput.stop();
+ QTest::qWait(40);
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
+
+ QVERIFY2((processedUs == 2000000),
+ QString("processedUSecs() doesn't equal file duration in us (%1)").arg(processedUs).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ QVERIFY2((audioOutput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
+ QVERIFY2((notifySignal.count() > 15 && notifySignal.count() < 25),
+ QString("too many notify() signals emitted (%1)").arg(notifySignal.count()).toLocal8Bit().constData());
+
+ audioFiles.at(i)->close();
+ }
+}
+
+void tst_QAudioOutput::pullSuspendResume()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioOutput audioOutput(testFormats.at(i), this);
+
+ audioOutput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioOutput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioOutput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioOutput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioFiles.at(i)->close();
+ audioFiles.at(i)->open(QIODevice::ReadOnly);
+ audioFiles.at(i)->seek(WavHeader::headerLength());
+
+ audioOutput.start(audioFiles.at(i));
+ // Check that QAudioOutput immediately transitions to ActiveState
+ QTRY_VERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal on start(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::ActiveState), "didn't transition to ActiveState after start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioOutput.periodSize() > 0);
+ stateSignal.clear();
+
+ // Wait for half of clip to play
+ QTest::qWait(1000);
+
+ audioOutput.suspend();
+
+ // Give backends running in separate threads a chance to suspend.
+ QTest::qWait(100);
+
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead")
+ .arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::SuspendedState), "didn't transition to SuspendedState after suspend()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after suspend()");
+ stateSignal.clear();
+
+ // Check that only 'elapsed', and not 'processed' increases while suspended
+ qint64 elapsedUs = audioOutput.elapsedUSecs();
+ qint64 processedUs = audioOutput.processedUSecs();
+ QTest::qWait(1000);
+ QVERIFY(audioOutput.elapsedUSecs() > elapsedUs);
+ QVERIFY(audioOutput.processedUSecs() == processedUs);
+
+ audioOutput.resume();
+
+ // Give backends running in separate threads a chance to suspend.
+ QTest::qWait(100);
+
+ // Check that QAudioOutput immediately transitions to ActiveState
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal after resume(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::ActiveState), "didn't transition to ActiveState after resume()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()");
+ stateSignal.clear();
+
+ // Wait until playback finishes
+ QTest::qWait(3000); // 3 seconds should be plenty
+
+ QVERIFY2(audioFiles.at(i)->atEnd(), "didn't play to EOF");
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit IdleState signal when at EOF, got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transitions to IdleState when at EOF");
+ stateSignal.clear();
+
+ processedUs = audioOutput.processedUSecs();
+
+ audioOutput.stop();
+ QTest::qWait(40);
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
+
+ QVERIFY2((processedUs == 2000000),
+ QString("processedUSecs() doesn't equal file duration in us (%1)").arg(processedUs).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ QVERIFY2((audioOutput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
+
+ audioFiles.at(i)->close();
+ }
+}
+
+void tst_QAudioOutput::push()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioOutput audioOutput(testFormats.at(i), this);
+
+ audioOutput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioOutput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioOutput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioOutput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioFiles.at(i)->close();
+ audioFiles.at(i)->open(QIODevice::ReadOnly);
+ audioFiles.at(i)->seek(WavHeader::headerLength());
+
+ QIODevice* feed = audioOutput.start();
+
+ // Check that QAudioOutput immediately transitions to IdleState
+ QTRY_VERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal on start(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transition to IdleState after start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioOutput.periodSize() > 0);
+ stateSignal.clear();
+
+ // Check that 'elapsed' increases
+ QTest::qWait(40);
+ QVERIFY2((audioOutput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
+ QVERIFY2((audioOutput.processedUSecs() == qint64(0)), "processedUSecs() is not zero after start()");
+
+ qint64 written = 0;
+ bool firstBuffer = true;
+ QByteArray buffer(AUDIO_BUFFER, 0);
+
+ while (written < audioFiles.at(i)->size()-WavHeader::headerLength()) {
+
+ if (audioOutput.bytesFree() >= audioOutput.periodSize()) {
+ qint64 len = audioFiles.at(i)->read(buffer.data(),audioOutput.periodSize());
+ written += feed->write(buffer.constData(), len);
+
+ if (firstBuffer) {
+ // Check for transition to ActiveState when data is provided
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal after receiving data, got %1 signals instead")
+ .arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::ActiveState), "didn't transition to ActiveState after receiving data");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after receiving data");
+ firstBuffer = false;
+ }
+ } else
+ QTest::qWait(20);
+ }
+ stateSignal.clear();
+
+ // Wait until playback finishes
+ QTest::qWait(3000); // 3 seconds should be plenty
+
+ QVERIFY2(audioFiles.at(i)->atEnd(), "didn't play to EOF");
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit IdleState signal when at EOF, got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transitions to IdleState when at EOF");
+ stateSignal.clear();
+
+ qint64 processedUs = audioOutput.processedUSecs();
+
+ audioOutput.stop();
+ QTest::qWait(40);
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
+
+ QVERIFY2((processedUs == 2000000),
+ QString("processedUSecs() doesn't equal file duration in us (%1)").arg(processedUs).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ QVERIFY2((audioOutput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
+ QVERIFY2((notifySignal.count() > 15 && notifySignal.count() < 25),
+ QString("too many notify() signals emitted (%1)").arg(notifySignal.count()).toLocal8Bit().constData());
+
+ audioFiles.at(i)->close();
+ }
+}
+
+void tst_QAudioOutput::pushSuspendResume()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioOutput audioOutput(testFormats.at(i), this);
+
+ audioOutput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioOutput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioOutput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioOutput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioFiles.at(i)->close();
+ audioFiles.at(i)->open(QIODevice::ReadOnly);
+ audioFiles.at(i)->seek(WavHeader::headerLength());
+
+ QIODevice* feed = audioOutput.start();
+
+ // Check that QAudioOutput immediately transitions to IdleState
+ QTRY_VERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal on start(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transition to IdleState after start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioOutput.periodSize() > 0);
+ stateSignal.clear();
+
+ // Check that 'elapsed' increases
+ QTest::qWait(40);
+ QVERIFY2((audioOutput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
+ QVERIFY2((audioOutput.processedUSecs() == qint64(0)), "processedUSecs() is not zero after start()");
+
+ qint64 written = 0;
+ bool firstBuffer = true;
+ QByteArray buffer(AUDIO_BUFFER, 0);
+
+ // Play half of the clip
+ while (written < (audioFiles.at(i)->size()-WavHeader::headerLength())/2) {
+
+ if (audioOutput.bytesFree() >= audioOutput.periodSize()) {
+ qint64 len = audioFiles.at(i)->read(buffer.data(),audioOutput.periodSize());
+ written += feed->write(buffer.constData(), len);
+
+ if (firstBuffer) {
+ // Check for transition to ActiveState when data is provided
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal after receiving data, got %1 signals instead")
+ .arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::ActiveState), "didn't transition to ActiveState after receiving data");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after receiving data");
+ firstBuffer = false;
+ }
+ } else
+ QTest::qWait(20);
+ }
+ stateSignal.clear();
+
+ audioOutput.suspend();
+
+ // Give backends running in separate threads a chance to suspend.
+ QTest::qWait(100);
+
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead")
+ .arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::SuspendedState), "didn't transition to SuspendedState after suspend()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after suspend()");
+ stateSignal.clear();
+
+ // Check that only 'elapsed', and not 'processed' increases while suspended
+ qint64 elapsedUs = audioOutput.elapsedUSecs();
+ qint64 processedUs = audioOutput.processedUSecs();
+ QTest::qWait(1000);
+ QVERIFY(audioOutput.elapsedUSecs() > elapsedUs);
+ QVERIFY(audioOutput.processedUSecs() == processedUs);
+
+ audioOutput.resume();
+
+ // Give backends running in separate threads a chance to suspend.
+ QTest::qWait(100);
+
+ // Check that QAudioOutput immediately transitions to ActiveState
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal after resume(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::ActiveState), "didn't transition to ActiveState after resume()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()");
+ stateSignal.clear();
+
+ // Play rest of the clip
+ while (!audioFiles.at(i)->atEnd()) {
+ if (audioOutput.bytesFree() >= audioOutput.periodSize()) {
+ qint64 len = audioFiles.at(i)->read(buffer.data(),audioOutput.periodSize());
+ written += feed->write(buffer.constData(), len);
+ } else
+ QTest::qWait(20);
+ }
+ stateSignal.clear();
+
+ // Wait until playback finishes
+ QTest::qWait(1000); // 1 seconds should be plenty
+
+ QVERIFY2(audioFiles.at(i)->atEnd(), "didn't play to EOF");
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit IdleState signal when at EOF, got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transitions to IdleState when at EOF");
+ stateSignal.clear();
+
+ processedUs = audioOutput.processedUSecs();
+
+ audioOutput.stop();
+ QTest::qWait(40);
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
+
+ QVERIFY2((processedUs == 2000000),
+ QString("processedUSecs() doesn't equal file duration in us (%1)").arg(processedUs).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ QVERIFY2((audioOutput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
+
+ audioFiles.at(i)->close();
+ }
+}
+
+void tst_QAudioOutput::pushUnderrun()
+{
+ for(int i=0; i<audioFiles.count(); i++) {
+ QAudioOutput audioOutput(testFormats.at(i), this);
+
+ audioOutput.setNotifyInterval(100);
+
+ QSignalSpy notifySignal(&audioOutput, SIGNAL(notify()));
+ QSignalSpy stateSignal(&audioOutput, SIGNAL(stateChanged(QAudio::State)));
+
+ // Check that we are in the default state before calling start
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
+ QVERIFY2((audioOutput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
+
+ audioFiles.at(i)->close();
+ audioFiles.at(i)->open(QIODevice::ReadOnly);
+ audioFiles.at(i)->seek(WavHeader::headerLength());
+
+ QIODevice* feed = audioOutput.start();
+
+ // Check that QAudioOutput immediately transitions to IdleState
+ QTRY_VERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal on start(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transition to IdleState after start()");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
+ QVERIFY(audioOutput.periodSize() > 0);
+ stateSignal.clear();
+
+ // Check that 'elapsed' increases
+ QTest::qWait(40);
+ QVERIFY2((audioOutput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
+ QVERIFY2((audioOutput.processedUSecs() == qint64(0)), "processedUSecs() is not zero after start()");
+
+ qint64 written = 0;
+ bool firstBuffer = true;
+ QByteArray buffer(AUDIO_BUFFER, 0);
+
+ // Play half of the clip
+ while (written < (audioFiles.at(i)->size()-WavHeader::headerLength())/2) {
+
+ if (audioOutput.bytesFree() >= audioOutput.periodSize()) {
+ qint64 len = audioFiles.at(i)->read(buffer.data(),audioOutput.periodSize());
+ written += feed->write(buffer.constData(), len);
+
+ if (firstBuffer) {
+ // Check for transition to ActiveState when data is provided
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal after receiving data, got %1 signals instead")
+ .arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::ActiveState), "didn't transition to ActiveState after receiving data");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after receiving data");
+ firstBuffer = false;
+ }
+ } else
+ QTest::qWait(20);
+ }
+ stateSignal.clear();
+
+ // Wait for data to be played
+ QTest::qWait(1000);
+
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit IdleState signal after suspend(), got %1 signals instead")
+ .arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transition to IdleState, no data");
+ QVERIFY2((audioOutput.error() == QAudio::UnderrunError), "error state is not equal to QAudio::UnderrunError, no data");
+ stateSignal.clear();
+
+ firstBuffer = true;
+ // Play rest of the clip
+ while (!audioFiles.at(i)->atEnd()) {
+ if (audioOutput.bytesFree() >= audioOutput.periodSize()) {
+ qint64 len = audioFiles.at(i)->read(buffer.data(),audioOutput.periodSize());
+ written += feed->write(buffer.constData(), len);
+ if (firstBuffer) {
+ // Check for transition to ActiveState when data is provided
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit signal after receiving data, got %1 signals instead")
+ .arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::ActiveState), "didn't transition to ActiveState after receiving data");
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after receiving data");
+ firstBuffer = false;
+ }
+ } else
+ QTest::qWait(20);
+ }
+ stateSignal.clear();
+
+ // Wait until playback finishes
+ QTest::qWait(1000); // 1 seconds should be plenty
+
+ QVERIFY2(audioFiles.at(i)->atEnd(), "didn't play to EOF");
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit IdleState signal when at EOF, got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transitions to IdleState when at EOF");
+ stateSignal.clear();
+
+ qint64 processedUs = audioOutput.processedUSecs();
+
+ audioOutput.stop();
+ QTest::qWait(40);
+ QVERIFY2((stateSignal.count() == 1),
+ QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
+
+ QVERIFY2((processedUs == 2000000),
+ QString("processedUSecs() doesn't equal file duration in us (%1)").arg(processedUs).toLocal8Bit().constData());
+ QVERIFY2((audioOutput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
+ QVERIFY2((audioOutput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
+
+ audioFiles.at(i)->close();
+ }
+}
+
+void tst_QAudioOutput::cleanupTestCase()
+{
+ QFile* file;
+
+ foreach (file, audioFiles) {
+ file->remove();
+ delete file;
+ }
+}
+
+QTEST_MAIN(tst_QAudioOutput)
+
+#include "tst_qaudiooutput.moc"
diff --git a/tests/auto/qaudiooutput/wavheader.cpp b/tests/auto/qaudiooutput/wavheader.cpp
new file mode 100755
index 000000000..26fcd6f98
--- /dev/null
+++ b/tests/auto/qaudiooutput/wavheader.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qendian.h>
+#include "wavheader.h"
+
+
+struct chunk
+{
+ char id[4];
+ quint32 size;
+};
+
+struct RIFFHeader
+{
+ chunk descriptor; // "RIFF"
+ char type[4]; // "WAVE"
+};
+
+struct WAVEHeader
+{
+ chunk descriptor;
+ quint16 audioFormat;
+ quint16 numChannels;
+ quint32 sampleRate;
+ quint32 byteRate;
+ quint16 blockAlign;
+ quint16 bitsPerSample;
+};
+
+struct DATAHeader
+{
+ chunk descriptor;
+};
+
+struct CombinedHeader
+{
+ RIFFHeader riff;
+ WAVEHeader wave;
+ DATAHeader data;
+};
+
+static const int HeaderLength = sizeof(CombinedHeader);
+
+
+WavHeader::WavHeader(const QAudioFormat &format, qint64 dataLength)
+ : m_format(format)
+ , m_dataLength(dataLength)
+{
+
+}
+
+bool WavHeader::read(QIODevice &device)
+{
+ bool result = true;
+
+ if (!device.isSequential())
+ result = device.seek(0);
+ // else, assume that current position is the start of the header
+
+ if (result) {
+ CombinedHeader header;
+ result = (device.read(reinterpret_cast<char *>(&header), HeaderLength) == HeaderLength);
+ if (result) {
+ if ((memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0
+ || memcmp(&header.riff.descriptor.id, "RIFX", 4) == 0)
+ && memcmp(&header.riff.type, "WAVE", 4) == 0
+ && memcmp(&header.wave.descriptor.id, "fmt ", 4) == 0
+ && header.wave.audioFormat == 1 // PCM
+ ) {
+ if (memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0)
+ m_format.setByteOrder(QAudioFormat::LittleEndian);
+ else
+ m_format.setByteOrder(QAudioFormat::BigEndian);
+
+ m_format.setChannels(qFromLittleEndian<quint16>(header.wave.numChannels));
+ m_format.setCodec("audio/pcm");
+ m_format.setFrequency(qFromLittleEndian<quint32>(header.wave.sampleRate));
+ m_format.setSampleSize(qFromLittleEndian<quint16>(header.wave.bitsPerSample));
+
+ switch(header.wave.bitsPerSample) {
+ case 8:
+ m_format.setSampleType(QAudioFormat::UnSignedInt);
+ break;
+ case 16:
+ m_format.setSampleType(QAudioFormat::SignedInt);
+ break;
+ default:
+ result = false;
+ }
+
+ m_dataLength = device.size() - HeaderLength;
+ } else {
+ result = false;
+ }
+ }
+ }
+
+ return result;
+}
+
+bool WavHeader::write(QIODevice &device)
+{
+ CombinedHeader header;
+
+ memset(&header, 0, HeaderLength);
+
+ // RIFF header
+ if (m_format.byteOrder() == QAudioFormat::LittleEndian)
+ memcpy(header.riff.descriptor.id,"RIFF",4);
+ else
+ memcpy(header.riff.descriptor.id,"RIFX",4);
+ qToLittleEndian<quint32>(quint32(m_dataLength + HeaderLength - 8),
+ reinterpret_cast<unsigned char*>(&header.riff.descriptor.size));
+ memcpy(header.riff.type, "WAVE",4);
+
+ // WAVE header
+ memcpy(header.wave.descriptor.id,"fmt ",4);
+ qToLittleEndian<quint32>(quint32(16),
+ reinterpret_cast<unsigned char*>(&header.wave.descriptor.size));
+ qToLittleEndian<quint16>(quint16(1),
+ reinterpret_cast<unsigned char*>(&header.wave.audioFormat));
+ qToLittleEndian<quint16>(quint16(m_format.channels()),
+ reinterpret_cast<unsigned char*>(&header.wave.numChannels));
+ qToLittleEndian<quint32>(quint32(m_format.frequency()),
+ reinterpret_cast<unsigned char*>(&header.wave.sampleRate));
+ qToLittleEndian<quint32>(quint32(m_format.frequency() * m_format.channels() * m_format.sampleSize() / 8),
+ reinterpret_cast<unsigned char*>(&header.wave.byteRate));
+ qToLittleEndian<quint16>(quint16(m_format.channels() * m_format.sampleSize() / 8),
+ reinterpret_cast<unsigned char*>(&header.wave.blockAlign));
+ qToLittleEndian<quint16>(quint16(m_format.sampleSize()),
+ reinterpret_cast<unsigned char*>(&header.wave.bitsPerSample));
+
+ // DATA header
+ memcpy(header.data.descriptor.id,"data",4);
+ qToLittleEndian<quint32>(quint32(m_dataLength),
+ reinterpret_cast<unsigned char*>(&header.data.descriptor.size));
+
+ return (device.write(reinterpret_cast<const char *>(&header), HeaderLength) == HeaderLength);
+}
+
+const QAudioFormat& WavHeader::format() const
+{
+ return m_format;
+}
+
+qint64 WavHeader::dataLength() const
+{
+ return m_dataLength;
+}
+
+qint64 WavHeader::headerLength()
+{
+ return HeaderLength;
+}
+
+bool WavHeader::writeDataLength(QIODevice &device, qint64 dataLength)
+{
+ bool result = false;
+ if (!device.isSequential()) {
+ device.seek(40);
+ unsigned char dataLengthLE[4];
+ qToLittleEndian<quint32>(quint32(dataLength), dataLengthLE);
+ result = (device.write(reinterpret_cast<const char *>(dataLengthLE), 4) == 4);
+ }
+ return result;
+}
diff --git a/tests/auto/qaudiooutput/wavheader.h b/tests/auto/qaudiooutput/wavheader.h
new file mode 100755
index 000000000..5212eca67
--- /dev/null
+++ b/tests/auto/qaudiooutput/wavheader.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef WAVHEADER_H
+#define WAVHEADER_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qfile.h>
+#include <qaudioformat.h>
+
+/**
+ * Helper class for parsing WAV file headers.
+ *
+ * See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
+ */
+class WavHeader
+{
+public:
+ WavHeader(const QAudioFormat &format = QAudioFormat(),
+ qint64 dataLength = 0);
+
+ // Reads WAV header and seeks to start of data
+ bool read(QIODevice &device);
+
+ // Writes WAV header
+ bool write(QIODevice &device);
+
+ const QAudioFormat& format() const;
+ qint64 dataLength() const;
+
+ static qint64 headerLength();
+
+ static bool writeDataLength(QIODevice &device, qint64 dataLength);
+
+private:
+ QAudioFormat m_format;
+ qint64 m_dataLength;
+};
+
+#endif
+
diff --git a/tests/auto/qcamera/qcamera.pro b/tests/auto/qcamera/qcamera.pro
new file mode 100644
index 000000000..6ebbe3182
--- /dev/null
+++ b/tests/auto/qcamera/qcamera.pro
@@ -0,0 +1,15 @@
+load(qttest_p4)
+
+QT += multimediakit-private
+
+# TARGET = tst_qcamera
+# CONFIG += testcase
+
+SOURCES += tst_qcamera.cpp
+
+symbian {
+ TARGET.CAPABILITY = ALL -TCB
+ TARGET.EPOCHEAPSIZE = 0x20000 0x3000000
+}
+
+maemo*:CONFIG += insignificant_test
diff --git a/tests/auto/qcamera/tst_qcamera.cpp b/tests/auto/qcamera/tst_qcamera.cpp
new file mode 100644
index 000000000..010309a0d
--- /dev/null
+++ b/tests/auto/qcamera/tst_qcamera.cpp
@@ -0,0 +1,2012 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include <QtTest/QtTest>
+#include <QDebug>
+
+#include <qabstractvideosurface.h>
+#include <qcameracontrol.h>
+#include <qcameralockscontrol.h>
+#include <qcameraexposurecontrol.h>
+#include <qcameraflashcontrol.h>
+#include <qcamerafocuscontrol.h>
+#include <qcameraimagecapturecontrol.h>
+#include <qimageencodercontrol.h>
+#include <qcameraimageprocessingcontrol.h>
+#include <qcameracapturebufferformatcontrol.h>
+#include <qcameracapturedestinationcontrol.h>
+#include <qmediaservice.h>
+#include <qcamera.h>
+#include <qcameraimagecapture.h>
+#include <qgraphicsvideoitem.h>
+#include <qvideorenderercontrol.h>
+#include <qvideowidget.h>
+#include <qvideowindowcontrol.h>
+
+QT_USE_NAMESPACE
+class MockCaptureControl;
+
+Q_DECLARE_METATYPE(QtMultimediaKit::MetaData)
+
+class MockCameraControl : public QCameraControl
+{
+ friend class MockCaptureControl;
+ Q_OBJECT
+public:
+ MockCameraControl(QObject *parent = 0):
+ QCameraControl(parent),
+ m_state(QCamera::UnloadedState),
+ m_captureMode(QCamera::CaptureStillImage),
+ m_status(QCamera::UnloadedStatus),
+ m_propertyChangesSupported(false)
+ {
+ }
+
+ ~MockCameraControl() {}
+
+ void start() { m_state = QCamera::ActiveState; }
+ virtual void stop() { m_state = QCamera::UnloadedState; }
+ QCamera::State state() const { return m_state; }
+ void setState(QCamera::State state) {
+ if (m_state != state) {
+ m_state = state;
+
+ switch (state) {
+ case QCamera::UnloadedState:
+ m_status = QCamera::UnloadedStatus;
+ break;
+ case QCamera::LoadedState:
+ m_status = QCamera::LoadedStatus;
+ break;
+ case QCamera::ActiveState:
+ m_status = QCamera::ActiveStatus;
+ break;
+ default:
+ emit error(QCamera::NotSupportedFeatureError, "State not supported.");
+ return;
+ }
+
+ emit stateChanged(m_state);
+ emit statusChanged(m_status);
+ }
+ }
+
+ QCamera::Status status() const { return m_status; }
+
+ QCamera::CaptureMode captureMode() const { return m_captureMode; }
+ void setCaptureMode(QCamera::CaptureMode mode)
+ {
+ if (m_captureMode != mode) {
+ if (m_state == QCamera::ActiveState)
+ QVERIFY(m_propertyChangesSupported);
+ m_captureMode = mode;
+ emit captureModeChanged(mode);
+ }
+ }
+
+ bool isCaptureModeSupported(QCamera::CaptureMode mode) const
+ {
+ return mode == QCamera::CaptureStillImage || mode == QCamera::CaptureVideo;
+ }
+
+ QCamera::LockTypes supportedLocks() const
+ {
+ return QCamera::LockExposure | QCamera::LockFocus | QCamera::LockWhiteBalance;
+ }
+
+ bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const
+ {
+ Q_UNUSED(changeType);
+ Q_UNUSED(status);
+ return m_propertyChangesSupported;
+ }
+
+ QCamera::State m_state;
+ QCamera::CaptureMode m_captureMode;
+ QCamera::Status m_status;
+ bool m_propertyChangesSupported;
+};
+
+
+class MockCameraLocksControl : public QCameraLocksControl
+{
+ Q_OBJECT
+public:
+ MockCameraLocksControl(QObject *parent = 0):
+ QCameraLocksControl(parent),
+ m_focusLock(QCamera::Unlocked),
+ m_exposureLock(QCamera::Unlocked)
+ {
+ }
+
+ ~MockCameraLocksControl() {}
+
+ QCamera::LockTypes supportedLocks() const
+ {
+ return QCamera::LockExposure | QCamera::LockFocus;
+ }
+
+ QCamera::LockStatus lockStatus(QCamera::LockType lock) const
+ {
+ switch (lock) {
+ case QCamera::LockExposure:
+ return m_exposureLock;
+ case QCamera::LockFocus:
+ return m_focusLock;
+ default:
+ return QCamera::Unlocked;
+ }
+ }
+
+ void searchAndLock(QCamera::LockTypes locks)
+ {
+ if (locks & QCamera::LockExposure) {
+ QCamera::LockStatus newStatus = locks & QCamera::LockFocus ? QCamera::Searching : QCamera::Locked;
+
+ if (newStatus != m_exposureLock)
+ emit lockStatusChanged(QCamera::LockExposure,
+ m_exposureLock = newStatus,
+ QCamera::UserRequest);
+ }
+
+ if (locks & QCamera::LockFocus) {
+ emit lockStatusChanged(QCamera::LockFocus,
+ m_focusLock = QCamera::Searching,
+ QCamera::UserRequest);
+
+ QTimer::singleShot(5, this, SLOT(focused()));
+ }
+ }
+
+ void unlock(QCamera::LockTypes locks) {
+ if (locks & QCamera::LockFocus && m_focusLock != QCamera::Unlocked) {
+ emit lockStatusChanged(QCamera::LockFocus,
+ m_focusLock = QCamera::Unlocked,
+ QCamera::UserRequest);
+ }
+
+ if (locks & QCamera::LockExposure && m_exposureLock != QCamera::Unlocked) {
+ emit lockStatusChanged(QCamera::LockExposure,
+ m_exposureLock = QCamera::Unlocked,
+ QCamera::UserRequest);
+ }
+ }
+
+private slots:
+ void focused()
+ {
+ if (m_focusLock == QCamera::Searching) {
+ emit lockStatusChanged(QCamera::LockFocus,
+ m_focusLock = QCamera::Locked,
+ QCamera::UserRequest);
+ }
+
+ if (m_exposureLock == QCamera::Searching) {
+ emit lockStatusChanged(QCamera::LockExposure,
+ m_exposureLock = QCamera::Locked,
+ QCamera::UserRequest);
+ }
+ }
+
+
+private:
+ QCamera::LockStatus m_focusLock;
+ QCamera::LockStatus m_exposureLock;
+};
+
+class MockCaptureControl : public QCameraImageCaptureControl
+{
+ Q_OBJECT
+public:
+ MockCaptureControl(MockCameraControl *cameraControl, QObject *parent = 0)
+ :QCameraImageCaptureControl(parent), m_cameraControl(cameraControl), m_captureRequest(0), m_ready(true), m_captureCanceled(false)
+ {
+ }
+
+ ~MockCaptureControl()
+ {
+ }
+
+ QCameraImageCapture::DriveMode driveMode() const { return QCameraImageCapture::SingleImageCapture; }
+ void setDriveMode(QCameraImageCapture::DriveMode) {}
+
+ bool isReadyForCapture() const { return m_ready && m_cameraControl->state() == QCamera::ActiveState; }
+
+ int capture(const QString &fileName)
+ {
+ if (isReadyForCapture()) {
+ m_fileName = fileName;
+ m_captureRequest++;
+ emit readyForCaptureChanged(m_ready = false);
+ QTimer::singleShot(5, this, SLOT(captured()));
+ return m_captureRequest;
+ } else {
+ emit error(-1, QCameraImageCapture::NotReadyError,
+ QLatin1String("Could not capture in stopped state"));
+ }
+
+ return -1;
+ }
+
+ void cancelCapture()
+ {
+ m_captureCanceled = true;
+ }
+
+private Q_SLOTS:
+ void captured()
+ {
+ if (!m_captureCanceled) {
+ emit imageCaptured(m_captureRequest, QImage());
+
+ emit imageMetadataAvailable(m_captureRequest,
+ QtMultimediaKit::FocalLengthIn35mmFilm,
+ QVariant(50));
+
+ emit imageMetadataAvailable(m_captureRequest,
+ QtMultimediaKit::DateTimeOriginal,
+ QVariant(QDateTime::currentDateTime()));
+
+ emit imageMetadataAvailable(m_captureRequest,
+ QLatin1String("Answer to the Ultimate Question of Life, the Universe, and Everything"),
+ QVariant(42));
+ }
+
+ if (!m_ready)
+ emit readyForCaptureChanged(m_ready = true);
+
+ if (!m_captureCanceled)
+ emit imageSaved(m_captureRequest, m_fileName);
+
+ m_captureCanceled = false;
+ }
+
+private:
+ MockCameraControl *m_cameraControl;
+ QString m_fileName;
+ int m_captureRequest;
+ bool m_ready;
+ bool m_captureCanceled;
+};
+
+class MockCaptureDestinationControl : public QCameraCaptureDestinationControl
+{
+ Q_OBJECT
+public:
+ MockCaptureDestinationControl(QObject *parent = 0):
+ QCameraCaptureDestinationControl(parent),
+ m_destination(QCameraImageCapture::CaptureToFile)
+ {
+ }
+
+ bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
+ {
+ return destination == QCameraImageCapture::CaptureToBuffer ||
+ destination == QCameraImageCapture::CaptureToFile;
+ }
+
+ QCameraImageCapture::CaptureDestinations captureDestination() const
+ {
+ return m_destination;
+ }
+
+ void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
+ {
+ if (isCaptureDestinationSupported(destination) && destination != m_destination) {
+ m_destination = destination;
+ emit captureDestinationChanged(m_destination);
+ }
+ }
+
+private:
+ QCameraImageCapture::CaptureDestinations m_destination;
+};
+
+class MockCaptureBufferFormatControl : public QCameraCaptureBufferFormatControl
+{
+ Q_OBJECT
+public:
+ MockCaptureBufferFormatControl(QObject *parent = 0):
+ QCameraCaptureBufferFormatControl(parent),
+ m_format(QVideoFrame::Format_Jpeg)
+ {
+ }
+
+ QList<QVideoFrame::PixelFormat> supportedBufferFormats() const
+ {
+ return QList<QVideoFrame::PixelFormat>()
+ << QVideoFrame::Format_Jpeg
+ << QVideoFrame::Format_RGB32
+ << QVideoFrame::Format_AdobeDng;
+ }
+
+ QVideoFrame::PixelFormat bufferFormat() const
+ {
+ return m_format;
+ }
+
+ void setBufferFormat(QVideoFrame::PixelFormat format)
+ {
+ if (format != m_format && supportedBufferFormats().contains(format)) {
+ m_format = format;
+ emit bufferFormatChanged(m_format);
+ }
+ }
+
+private:
+ QVideoFrame::PixelFormat m_format;
+};
+
+class MockCameraExposureControl : public QCameraExposureControl
+{
+ Q_OBJECT
+public:
+ MockCameraExposureControl(QObject *parent = 0):
+ QCameraExposureControl(parent),
+ m_aperture(2.8),
+ m_shutterSpeed(0.01),
+ m_isoSensitivity(100),
+ m_meteringMode(QCameraExposure::MeteringMatrix),
+ m_exposureCompensation(0),
+ m_exposureMode(QCameraExposure::ExposureAuto),
+ m_flashMode(QCameraExposure::FlashAuto)
+ {
+ }
+
+ ~MockCameraExposureControl() {}
+
+ QCameraExposure::FlashModes flashMode() const
+ {
+ return m_flashMode;
+ }
+
+ void setFlashMode(QCameraExposure::FlashModes mode)
+ {
+ if (isFlashModeSupported(mode)) {
+ m_flashMode = mode;
+ }
+ }
+
+ bool isFlashModeSupported(QCameraExposure::FlashModes mode) const
+ {
+ return mode & (QCameraExposure::FlashAuto | QCameraExposure::FlashOff | QCameraExposure::FlashOn);
+ }
+
+ bool isFlashReady() const
+ {
+ return true;
+ }
+
+ QCameraExposure::ExposureMode exposureMode() const
+ {
+ return m_exposureMode;
+ }
+
+ void setExposureMode(QCameraExposure::ExposureMode mode)
+ {
+ if (isExposureModeSupported(mode))
+ m_exposureMode = mode;
+ }
+
+ bool isExposureModeSupported(QCameraExposure::ExposureMode mode) const
+ {
+ return mode == QCameraExposure::ExposureAuto ||
+ mode == QCameraExposure::ExposureManual;
+ }
+
+ bool isParameterSupported(ExposureParameter parameter) const
+ {
+ switch (parameter) {
+ case QCameraExposureControl::ExposureCompensation:
+ case QCameraExposureControl::ISO:
+ case QCameraExposureControl::Aperture:
+ case QCameraExposureControl::ShutterSpeed:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ QVariant exposureParameter(ExposureParameter parameter) const
+ {
+ switch (parameter) {
+ case QCameraExposureControl::ExposureCompensation:
+ return QVariant(m_exposureCompensation);
+ case QCameraExposureControl::ISO:
+ return QVariant(m_isoSensitivity);
+ case QCameraExposureControl::Aperture:
+ return QVariant(m_aperture);
+ case QCameraExposureControl::ShutterSpeed:
+ return QVariant(m_shutterSpeed);
+ default:
+ return QVariant();
+ }
+ }
+
+ QVariantList supportedParameterRange(ExposureParameter parameter) const
+ {
+ QVariantList res;
+ switch (parameter) {
+ case QCameraExposureControl::ExposureCompensation:
+ res << -2.0 << 2.0;
+ break;
+ case QCameraExposureControl::ISO:
+ res << 100 << 200 << 400 << 800;
+ break;
+ case QCameraExposureControl::Aperture:
+ res << 2.8 << 4.0 << 5.6 << 8.0 << 11.0 << 16.0;
+ break;
+ case QCameraExposureControl::ShutterSpeed:
+ res << 0.001 << 0.01 << 0.1 << 1.0;
+ break;
+ default:
+ break;
+ }
+
+ return res;
+ }
+
+ ParameterFlags exposureParameterFlags(ExposureParameter parameter) const
+ {
+ ParameterFlags res = 0;
+ switch (parameter) {
+ case QCameraExposureControl::ExposureCompensation:
+ case QCameraExposureControl::Aperture:
+ case QCameraExposureControl::ShutterSpeed:
+ res |= ContinuousRange;
+ default:
+ break;
+ }
+
+ return res;
+ }
+
+ bool setExposureParameter(ExposureParameter parameter, const QVariant& value)
+ {
+ switch (parameter) {
+ case QCameraExposureControl::ExposureCompensation:
+ m_exposureCompensation = qBound<qreal>(-2.0, value.toReal(), 2.0);
+ break;
+ case QCameraExposureControl::ISO:
+ m_isoSensitivity = 100*qRound(qBound(100, value.toInt(), 800)/100.0);
+ break;
+ case QCameraExposureControl::Aperture:
+ m_aperture = qBound<qreal>(2.8, value.toReal(), 16.0);
+ break;
+ case QCameraExposureControl::ShutterSpeed:
+ m_shutterSpeed = qBound<qreal>(0.001, value.toReal(), 1.0);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+ }
+
+ QString extendedParameterName(ExposureParameter)
+ {
+ return QString();
+ }
+
+ QCameraExposure::MeteringMode meteringMode() const
+ {
+ return m_meteringMode;
+ }
+
+ void setMeteringMode(QCameraExposure::MeteringMode mode)
+ {
+ if (isMeteringModeSupported(mode))
+ m_meteringMode = mode;
+ }
+
+ bool isMeteringModeSupported(QCameraExposure::MeteringMode mode) const
+ {
+ return mode == QCameraExposure::MeteringAverage
+ || mode == QCameraExposure::MeteringMatrix;
+ }
+
+private:
+ qreal m_aperture;
+ qreal m_shutterSpeed;
+ int m_isoSensitivity;
+ QCameraExposure::MeteringMode m_meteringMode;
+ qreal m_exposureCompensation;
+ QCameraExposure::ExposureMode m_exposureMode;
+ QCameraExposure::FlashModes m_flashMode;
+};
+
+class MockCameraFlashControl : public QCameraFlashControl
+{
+ Q_OBJECT
+public:
+ MockCameraFlashControl(QObject *parent = 0):
+ QCameraFlashControl(parent),
+ m_flashMode(QCameraExposure::FlashAuto)
+ {
+ }
+
+ ~MockCameraFlashControl() {}
+
+ QCameraExposure::FlashModes flashMode() const
+ {
+ return m_flashMode;
+ }
+
+ void setFlashMode(QCameraExposure::FlashModes mode)
+ {
+ if (isFlashModeSupported(mode)) {
+ m_flashMode = mode;
+ }
+ }
+
+ bool isFlashModeSupported(QCameraExposure::FlashModes mode) const
+ {
+ return mode & (QCameraExposure::FlashAuto | QCameraExposure::FlashOff | QCameraExposure::FlashOn);
+ }
+
+ bool isFlashReady() const
+ {
+ return true;
+ }
+
+private:
+ QCameraExposure::FlashModes m_flashMode;
+};
+
+
+class MockCameraFocusControl : public QCameraFocusControl
+{
+ Q_OBJECT
+public:
+ MockCameraFocusControl(QObject *parent = 0):
+ QCameraFocusControl(parent),
+ m_opticalZoom(1.0),
+ m_digitalZoom(1.0),
+ m_focusMode(QCameraFocus::AutoFocus),
+ m_focusPointMode(QCameraFocus::FocusPointAuto),
+ m_focusPoint(0.5, 0.5)
+ {
+ }
+
+ ~MockCameraFocusControl() {}
+
+ QCameraFocus::FocusMode focusMode() const
+ {
+ return m_focusMode;
+ }
+
+ void setFocusMode(QCameraFocus::FocusMode mode)
+ {
+ if (isFocusModeSupported(mode))
+ m_focusMode = mode;
+ }
+
+ bool isFocusModeSupported(QCameraFocus::FocusMode mode) const
+ {
+ return mode == QCameraFocus::AutoFocus || mode == QCameraFocus::ContinuousFocus;
+ }
+
+ qreal maximumOpticalZoom() const
+ {
+ return 3.0;
+ }
+
+ qreal maximumDigitalZoom() const
+ {
+ return 4.0;
+ }
+
+ qreal opticalZoom() const
+ {
+ return m_opticalZoom;
+ }
+
+ qreal digitalZoom() const
+ {
+ return m_digitalZoom;
+ }
+
+ void zoomTo(qreal optical, qreal digital)
+ {
+ optical = qBound<qreal>(1.0, optical, maximumOpticalZoom());
+ digital = qBound<qreal>(1.0, digital, maximumDigitalZoom());
+
+ if (!qFuzzyCompare(digital, m_digitalZoom)) {
+ m_digitalZoom = digital;
+ emit digitalZoomChanged(m_digitalZoom);
+ }
+
+ if (!qFuzzyCompare(optical, m_opticalZoom)) {
+ m_opticalZoom = optical;
+ emit opticalZoomChanged(m_opticalZoom);
+ }
+ }
+
+ QCameraFocus::FocusPointMode focusPointMode() const
+ {
+ return m_focusPointMode;
+ }
+
+ void setFocusPointMode(QCameraFocus::FocusPointMode mode)
+ {
+ if (isFocusPointModeSupported(mode))
+ m_focusPointMode = mode;
+ }
+
+ bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const
+ {
+ switch (mode) {
+ case QCameraFocus::FocusPointAuto:
+ case QCameraFocus::FocusPointCenter:
+ case QCameraFocus::FocusPointCustom:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ QPointF customFocusPoint() const
+ {
+ return m_focusPoint;
+ }
+
+ void setCustomFocusPoint(const QPointF &point)
+ {
+ m_focusPoint = point;
+ }
+
+ QCameraFocusZoneList focusZones() const { return QCameraFocusZoneList() << QCameraFocusZone(QRectF(0.45, 0.45, 0.1, 0.1)); }
+
+
+private:
+ qreal m_opticalZoom;
+ qreal m_digitalZoom;
+ QCameraFocus::FocusMode m_focusMode;
+ QCameraFocus::FocusPointMode m_focusPointMode;
+ QPointF m_focusPoint;
+};
+
+class MockImageProcessingControl : public QCameraImageProcessingControl
+{
+ Q_OBJECT
+public:
+ MockImageProcessingControl(QObject *parent = 0)
+ : QCameraImageProcessingControl(parent)
+ {
+ m_supportedWhiteBalance.insert(QCameraImageProcessing::WhiteBalanceAuto);
+ }
+
+ QCameraImageProcessing::WhiteBalanceMode whiteBalanceMode() const { return m_whiteBalanceMode; }
+ void setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode) { m_whiteBalanceMode = mode; }
+
+ bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const {
+ return m_supportedWhiteBalance.contains(mode); }
+
+ void setSupportedWhiteBalanceModes(QSet<QCameraImageProcessing::WhiteBalanceMode> modes) {
+ m_supportedWhiteBalance = modes; }
+
+ bool isProcessingParameterSupported(ProcessingParameter parameter) const
+ {
+ return parameter == Contrast || parameter == Sharpening || parameter == ColorTemperature;
+ }
+ QVariant processingParameter(ProcessingParameter parameter) const
+ {
+ switch (parameter) {
+ case Contrast:
+ return m_contrast;
+ case Sharpening:
+ return m_sharpeningLevel;
+ case ColorTemperature:
+ return m_manualWhiteBalance;
+ default:
+ return QVariant();
+ }
+ }
+ void setProcessingParameter(ProcessingParameter parameter, QVariant value)
+ {
+ switch (parameter) {
+ case Contrast:
+ m_contrast = value;
+ break;
+ case Sharpening:
+ m_sharpeningLevel = value;
+ break;
+ case ColorTemperature:
+ m_manualWhiteBalance = value;
+ break;
+ default:
+ break;
+ }
+ }
+
+
+private:
+ QCameraImageProcessing::WhiteBalanceMode m_whiteBalanceMode;
+ QSet<QCameraImageProcessing::WhiteBalanceMode> m_supportedWhiteBalance;
+ QVariant m_manualWhiteBalance;
+ QVariant m_contrast;
+ QVariant m_sharpeningLevel;
+};
+
+class MockImageEncoderControl : public QImageEncoderControl
+{
+public:
+ MockImageEncoderControl(QObject *parent = 0)
+ : QImageEncoderControl(parent)
+ {
+ }
+
+ QList<QSize> supportedResolutions(const QImageEncoderSettings & = QImageEncoderSettings(),
+ bool *continuous = 0) const
+ {
+ if (continuous)
+ *continuous = true;
+
+ return m_supportedResolutions;
+ }
+
+ void setSupportedResolutions(const QList<QSize> &resolutions) {
+ m_supportedResolutions = resolutions; }
+
+ QStringList supportedImageCodecs() const { return m_supportedCodecs; }
+ void setSupportedImageCodecs(const QStringList &codecs) { m_supportedCodecs = codecs; }
+
+ QString imageCodecDescription(const QString &codecName) const {
+ return m_codecDescriptions.value(codecName); }
+ void setImageCodecDescriptions(const QMap<QString, QString> &descriptions) {
+ m_codecDescriptions = descriptions; }
+
+ QImageEncoderSettings imageSettings() const { return m_settings; }
+ void setImageSettings(const QImageEncoderSettings &settings) { m_settings = settings; }
+
+private:
+ QImageEncoderSettings m_settings;
+
+ QList<QSize> m_supportedResolutions;
+ QStringList m_supportedCodecs;
+ QMap<QString, QString> m_codecDescriptions;
+};
+
+class MockVideoSurface : public QAbstractVideoSurface
+{
+public:
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ const QAbstractVideoBuffer::HandleType) const
+ {
+ return QList<QVideoFrame::PixelFormat>();
+ }
+
+ bool present(const QVideoFrame &) { return false; }
+};
+
+class MockVideoRendererControl : public QVideoRendererControl
+{
+public:
+ MockVideoRendererControl(QObject *parent) : QVideoRendererControl(parent), m_surface(0) {}
+
+ QAbstractVideoSurface *surface() const { return m_surface; }
+ void setSurface(QAbstractVideoSurface *surface) { m_surface = surface; }
+
+ QAbstractVideoSurface *m_surface;
+};
+
+class MockVideoWindowControl : public QVideoWindowControl
+{
+public:
+ MockVideoWindowControl(QObject *parent) : QVideoWindowControl(parent) {}
+ WId winId() const { return 0; }
+ void setWinId(WId) {}
+ QRect displayRect() const { return QRect(); }
+ void setDisplayRect(const QRect &) {}
+ bool isFullScreen() const { return false; }
+ void setFullScreen(bool) {}
+ void repaint() {}
+ QSize nativeSize() const { return QSize(); }
+ Qt::AspectRatioMode aspectRatioMode() const { return Qt::KeepAspectRatio; }
+ void setAspectRatioMode(Qt::AspectRatioMode) {}
+ int brightness() const { return 0; }
+ void setBrightness(int) {}
+ int contrast() const { return 0; }
+ void setContrast(int) {}
+ int hue() const { return 0; }
+ void setHue(int) {}
+ int saturation() const { return 0; }
+ void setSaturation(int) {}
+};
+
+class MockSimpleCameraService : public QMediaService
+{
+ Q_OBJECT
+
+public:
+ MockSimpleCameraService(): QMediaService(0)
+ {
+ mockControl = new MockCameraControl(this);
+ }
+
+ ~MockSimpleCameraService()
+ {
+ }
+
+ QMediaControl* requestControl(const char *iid)
+ {
+ if (qstrcmp(iid, QCameraControl_iid) == 0)
+ return mockControl;
+ return 0;
+ }
+
+ void releaseControl(QMediaControl*) {}
+
+ MockCameraControl *mockControl;
+};
+
+class MockCameraService : public QMediaService
+{
+ Q_OBJECT
+
+public:
+ MockCameraService(): QMediaService(0)
+ {
+ mockControl = new MockCameraControl(this);
+ mockLocksControl = new MockCameraLocksControl(this);
+ mockExposureControl = new MockCameraExposureControl(this);
+ mockFlashControl = new MockCameraFlashControl(this);
+ mockFocusControl = new MockCameraFocusControl(this);
+ mockCaptureControl = new MockCaptureControl(mockControl, this);
+ mockCaptureBufferControl = new MockCaptureBufferFormatControl(this);
+ mockCaptureDestinationControl = new MockCaptureDestinationControl(this);
+ mockImageProcessingControl = new MockImageProcessingControl(this);
+ mockImageEncoderControl = new MockImageEncoderControl(this);
+ rendererControl = new MockVideoRendererControl(this);
+ windowControl = new MockVideoWindowControl(this);
+ rendererRef = 0;
+ windowRef = 0;
+ }
+
+ ~MockCameraService()
+ {
+ }
+
+ QMediaControl* requestControl(const char *iid)
+ {
+ if (qstrcmp(iid, QCameraControl_iid) == 0)
+ return mockControl;
+
+ if (qstrcmp(iid, QCameraLocksControl_iid) == 0)
+ return mockLocksControl;
+
+ if (qstrcmp(iid, QCameraExposureControl_iid) == 0)
+ return mockExposureControl;
+
+ if (qstrcmp(iid, QCameraFlashControl_iid) == 0)
+ return mockFlashControl;
+
+ if (qstrcmp(iid, QCameraFocusControl_iid) == 0)
+ return mockFocusControl;
+
+ if (qstrcmp(iid, QCameraImageCaptureControl_iid) == 0)
+ return mockCaptureControl;
+
+ if (qstrcmp(iid, QCameraCaptureBufferFormatControl_iid) == 0)
+ return mockCaptureBufferControl;
+
+ if (qstrcmp(iid, QCameraCaptureDestinationControl_iid) == 0)
+ return mockCaptureDestinationControl;
+
+ if (qstrcmp(iid, QCameraImageProcessingControl_iid) == 0)
+ return mockImageProcessingControl;
+
+ if (qstrcmp(iid, QImageEncoderControl_iid) == 0)
+ return mockImageEncoderControl;
+
+ if (qstrcmp(iid, QVideoRendererControl_iid) == 0) {
+ if (rendererRef == 0) {
+ rendererRef += 1;
+ return rendererControl;
+ }
+ } else if (qstrcmp(iid, QVideoWindowControl_iid) == 0) {
+ if (windowRef == 0) {
+ windowRef += 1;
+ return windowControl;
+ }
+ }
+ return 0;
+ }
+
+ void releaseControl(QMediaControl *control)
+ {
+ if (control == rendererControl)
+ rendererRef -= 1;
+ else if (control == windowControl)
+ windowRef -= 1;
+ }
+
+ MockCameraControl *mockControl;
+ MockCameraLocksControl *mockLocksControl;
+ MockCaptureControl *mockCaptureControl;
+ MockCaptureBufferFormatControl *mockCaptureBufferControl;
+ MockCaptureDestinationControl *mockCaptureDestinationControl;
+ MockCameraExposureControl *mockExposureControl;
+ MockCameraFlashControl *mockFlashControl;
+ MockCameraFocusControl *mockFocusControl;
+ MockImageProcessingControl *mockImageProcessingControl;
+ MockImageEncoderControl *mockImageEncoderControl;
+ MockVideoRendererControl *rendererControl;
+ MockVideoWindowControl *windowControl;
+ int rendererRef;
+ int windowRef;
+};
+
+class MockProvider : public QMediaServiceProvider
+{
+public:
+ QMediaService *requestService(const QByteArray &, const QMediaServiceProviderHint &)
+ {
+ return service;
+ }
+
+ void releaseService(QMediaService *) {}
+
+ QMediaService *service;
+};
+
+
+class tst_QCamera: public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ void testAvailableDevices();
+ void testDeviceDescription();
+ void testCtorWithDevice();
+ void testSimpleCamera();
+ void testSimpleCameraWhiteBalance();
+ void testSimpleCameraExposure();
+ void testSimpleCameraFocus();
+ void testSimpleCameraCapture();
+ void testSimpleCameraLock();
+ void testSimpleCaptureDestination();
+ void testSimpleCaptureFormat();
+
+ void testCameraWhiteBalance();
+ void testCameraExposure();
+ void testCameraFocus();
+ void testCameraCapture();
+ void testCameraCaptureMetadata();
+ void testImageSettings();
+ void testCameraLock();
+ void testCameraLockCancel();
+ void testCameraEncodingProperyChange();
+ void testCaptureDestination();
+ void testCaptureFormat();
+
+
+ void testSetVideoOutput();
+ void testSetVideoOutputNoService();
+ void testSetVideoOutputNoControl();
+ void testSetVideoOutputDestruction();
+
+ void testEnumDebug();
+
+private:
+ MockSimpleCameraService *mockSimpleCameraService;
+ MockProvider *provider;
+};
+
+void tst_QCamera::initTestCase()
+{
+ provider = new MockProvider;
+ mockSimpleCameraService = new MockSimpleCameraService;
+ provider->service = mockSimpleCameraService;
+ qRegisterMetaType<QtMultimediaKit::MetaData>("QtMultimediaKit::MetaData");
+}
+
+void tst_QCamera::cleanupTestCase()
+{
+ delete mockSimpleCameraService;
+ delete provider;
+}
+
+void tst_QCamera::testAvailableDevices()
+{
+ int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();
+
+ QVERIFY(QCamera::availableDevices().count() == deviceCount);
+}
+
+void tst_QCamera::testDeviceDescription()
+{
+ int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();
+
+ if (deviceCount == 0)
+ QVERIFY(QCamera::deviceDescription(QByteArray("random")).isNull());
+ else {
+ foreach (const QByteArray &device, QCamera::availableDevices())
+ QVERIFY(QCamera::deviceDescription(device).length() > 0);
+ }
+}
+
+void tst_QCamera::testCtorWithDevice()
+{
+ int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();
+ QCamera *camera = 0;
+
+ if (deviceCount == 0) {
+ camera = new QCamera("random");
+ QVERIFY(camera->error() == QCamera::ServiceMissingError);
+ }
+ else {
+ camera = new QCamera(QCamera::availableDevices().first());
+ QVERIFY(camera->error() == QCamera::NoError);
+ }
+
+ delete camera;
+}
+
+void tst_QCamera::testSimpleCamera()
+{
+ QCamera camera(0, provider);
+ QCOMPARE(camera.service(), (QMediaService*)mockSimpleCameraService);
+
+ QCOMPARE(camera.state(), QCamera::UnloadedState);
+ camera.start();
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ camera.stop();
+ QCOMPARE(camera.state(), QCamera::LoadedState);
+ camera.unload();
+ QCOMPARE(camera.state(), QCamera::UnloadedState);
+ camera.load();
+ QCOMPARE(camera.state(), QCamera::LoadedState);
+}
+
+void tst_QCamera::testSimpleCameraWhiteBalance()
+{
+ QCamera camera(0, provider);
+
+ //only WhiteBalanceAuto is supported
+ QVERIFY(!camera.imageProcessing()->isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceAuto));
+ QVERIFY(!camera.imageProcessing()->isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceCloudy));
+ QCOMPARE(camera.imageProcessing()->whiteBalanceMode(), QCameraImageProcessing::WhiteBalanceAuto);
+ camera.imageProcessing()->setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceCloudy);
+ QCOMPARE(camera.imageProcessing()->whiteBalanceMode(), QCameraImageProcessing::WhiteBalanceAuto);
+ QCOMPARE(camera.imageProcessing()->manualWhiteBalance(), 0);
+ camera.imageProcessing()->setManualWhiteBalance(5000);
+ QCOMPARE(camera.imageProcessing()->manualWhiteBalance(), 0);
+}
+
+void tst_QCamera::testSimpleCameraExposure()
+{
+ QCamera camera(0, provider);
+ QCameraExposure *cameraExposure = camera.exposure();
+ QVERIFY(cameraExposure != 0);
+
+ QVERIFY(!cameraExposure->isExposureModeSupported(QCameraExposure::ExposureAuto));
+ QCOMPARE(cameraExposure->exposureMode(), QCameraExposure::ExposureAuto);
+ cameraExposure->setExposureMode(QCameraExposure::ExposureManual);//should be ignored
+ QCOMPARE(cameraExposure->exposureMode(), QCameraExposure::ExposureAuto);
+
+ QVERIFY(!cameraExposure->isFlashModeSupported(QCameraExposure::FlashOff));
+ QCOMPARE(cameraExposure->flashMode(), QCameraExposure::FlashOff);
+ QCOMPARE(cameraExposure->isFlashReady(), false);
+ cameraExposure->setFlashMode(QCameraExposure::FlashOn);
+ QCOMPARE(cameraExposure->flashMode(), QCameraExposure::FlashOff);
+
+ QVERIFY(!cameraExposure->isMeteringModeSupported(QCameraExposure::MeteringAverage));
+ QVERIFY(!cameraExposure->isMeteringModeSupported(QCameraExposure::MeteringSpot));
+ QVERIFY(!cameraExposure->isMeteringModeSupported(QCameraExposure::MeteringMatrix));
+ QCOMPARE(cameraExposure->meteringMode(), QCameraExposure::MeteringMatrix);
+ cameraExposure->setMeteringMode(QCameraExposure::MeteringSpot);
+ QCOMPARE(cameraExposure->meteringMode(), QCameraExposure::MeteringMatrix);
+
+ QCOMPARE(cameraExposure->exposureCompensation(), 0.0);
+ cameraExposure->setExposureCompensation(2.0);
+ QCOMPARE(cameraExposure->exposureCompensation(), 0.0);
+
+ QCOMPARE(cameraExposure->isoSensitivity(), -1);
+ QVERIFY(cameraExposure->supportedIsoSensitivities().isEmpty());
+ cameraExposure->setManualIsoSensitivity(100);
+ QCOMPARE(cameraExposure->isoSensitivity(), -1);
+ cameraExposure->setAutoIsoSensitivity();
+ QCOMPARE(cameraExposure->isoSensitivity(), -1);
+
+ QVERIFY(cameraExposure->aperture() < 0);
+ QVERIFY(cameraExposure->supportedApertures().isEmpty());
+ cameraExposure->setAutoAperture();
+ QVERIFY(cameraExposure->aperture() < 0);
+ cameraExposure->setManualAperture(5.6);
+ QVERIFY(cameraExposure->aperture() < 0);
+
+ QVERIFY(cameraExposure->shutterSpeed() < 0);
+ QVERIFY(cameraExposure->supportedShutterSpeeds().isEmpty());
+ cameraExposure->setAutoShutterSpeed();
+ QVERIFY(cameraExposure->shutterSpeed() < 0);
+ cameraExposure->setManualShutterSpeed(1/128.0);
+ QVERIFY(cameraExposure->shutterSpeed() < 0);
+}
+
+void tst_QCamera::testSimpleCameraFocus()
+{
+ QCamera camera(0, provider);
+
+ QCameraFocus *cameraFocus = camera.focus();
+ QVERIFY(cameraFocus != 0);
+
+ QVERIFY(!cameraFocus->isFocusModeSupported(QCameraFocus::AutoFocus));
+ QVERIFY(!cameraFocus->isFocusModeSupported(QCameraFocus::ContinuousFocus));
+ QVERIFY(!cameraFocus->isFocusModeSupported(QCameraFocus::InfinityFocus));
+
+ QCOMPARE(cameraFocus->focusMode(), QCameraFocus::AutoFocus);
+ QTest::ignoreMessage(QtWarningMsg, "Focus points mode selection is not supported");
+ cameraFocus->setFocusMode(QCameraFocus::ContinuousFocus);
+ QCOMPARE(cameraFocus->focusMode(), QCameraFocus::AutoFocus);
+
+ QCOMPARE(cameraFocus->maximumOpticalZoom(), 1.0);
+ QCOMPARE(cameraFocus->maximumDigitalZoom(), 1.0);
+ QCOMPARE(cameraFocus->opticalZoom(), 1.0);
+ QCOMPARE(cameraFocus->digitalZoom(), 1.0);
+
+ QTest::ignoreMessage(QtWarningMsg, "The camera doesn't support zooming.");
+ cameraFocus->zoomTo(100.0, 100.0);
+ QCOMPARE(cameraFocus->opticalZoom(), 1.0);
+ QCOMPARE(cameraFocus->digitalZoom(), 1.0);
+
+
+ QVERIFY(!cameraFocus->isFocusPointModeSupported(QCameraFocus::FocusPointAuto));
+ QCOMPARE(cameraFocus->focusPointMode(), QCameraFocus::FocusPointAuto);
+
+
+ cameraFocus->setFocusPointMode( QCameraFocus::FocusPointCenter );
+ QCOMPARE(cameraFocus->focusPointMode(), QCameraFocus::FocusPointAuto);
+
+ QCOMPARE(cameraFocus->customFocusPoint(), QPointF(0.5, 0.5));
+ QTest::ignoreMessage(QtWarningMsg, "Focus points selection is not supported");
+ cameraFocus->setCustomFocusPoint(QPointF(1.0, 1.0));
+ QCOMPARE(cameraFocus->customFocusPoint(), QPointF(0.5, 0.5));
+}
+
+void tst_QCamera::testSimpleCameraCapture()
+{
+ QCamera camera(0, provider);
+ QCameraImageCapture imageCapture(&camera);
+
+ QVERIFY(!imageCapture.isReadyForCapture());
+ QVERIFY(!imageCapture.isAvailable());
+
+ QCOMPARE(imageCapture.error(), QCameraImageCapture::NoError);
+ QVERIFY(imageCapture.errorString().isEmpty());
+
+ QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int, QCameraImageCapture::Error,QString)));
+ imageCapture.capture(QString::fromLatin1("/dev/null"));
+ QCOMPARE(errorSignal.size(), 1);
+ QCOMPARE(imageCapture.error(), QCameraImageCapture::NotSupportedFeatureError);
+ QVERIFY(!imageCapture.errorString().isEmpty());
+}
+
+void tst_QCamera::testSimpleCameraLock()
+{
+ QCamera camera(0, provider);
+ QCOMPARE(camera.lockStatus(), QCamera::Unlocked);
+ QCOMPARE(camera.lockStatus(QCamera::LockExposure), QCamera::Unlocked);
+ QCOMPARE(camera.lockStatus(QCamera::LockFocus), QCamera::Unlocked);
+ QCOMPARE(camera.lockStatus(QCamera::LockWhiteBalance), QCamera::Unlocked);
+
+ QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
+ QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
+ QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
+
+ camera.searchAndLock();
+ QCOMPARE(camera.lockStatus(), QCamera::Locked);
+ QCOMPARE(camera.lockStatus(QCamera::LockExposure), QCamera::Locked);
+ QCOMPARE(camera.lockStatus(QCamera::LockFocus), QCamera::Locked);
+ QCOMPARE(camera.lockStatus(QCamera::LockWhiteBalance), QCamera::Locked);
+ QCOMPARE(lockedSignal.count(), 1);
+ QCOMPARE(lockFailedSignal.count(), 0);
+ QCOMPARE(lockStatusChangedSignal.count(), 1);
+
+ lockedSignal.clear();
+ lockFailedSignal.clear();
+ lockStatusChangedSignal.clear();
+
+ camera.unlock();
+ QCOMPARE(camera.lockStatus(), QCamera::Unlocked);
+ QCOMPARE(camera.lockStatus(QCamera::LockExposure), QCamera::Unlocked);
+ QCOMPARE(camera.lockStatus(QCamera::LockFocus), QCamera::Unlocked);
+ QCOMPARE(camera.lockStatus(QCamera::LockWhiteBalance), QCamera::Unlocked);
+
+ QCOMPARE(lockedSignal.count(), 0);
+ QCOMPARE(lockFailedSignal.count(), 0);
+ QCOMPARE(lockStatusChangedSignal.count(), 1);
+}
+
+void tst_QCamera::testSimpleCaptureDestination()
+{
+ QCamera camera(0, provider);
+ QCameraImageCapture imageCapture(&camera);
+
+ QVERIFY(imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToFile));
+ QVERIFY(!imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer));
+ QVERIFY(!imageCapture.isCaptureDestinationSupported(
+ QCameraImageCapture::CaptureToBuffer | QCameraImageCapture::CaptureToFile));
+
+ QCOMPARE(imageCapture.captureDestination(), QCameraImageCapture::CaptureToFile);
+ imageCapture.setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
+ QCOMPARE(imageCapture.captureDestination(), QCameraImageCapture::CaptureToFile);
+}
+
+void tst_QCamera::testSimpleCaptureFormat()
+{
+ QCamera camera(0, provider);
+ QCameraImageCapture imageCapture(&camera);
+
+ QCOMPARE(imageCapture.bufferFormat(), QVideoFrame::Format_Invalid);
+ QVERIFY(imageCapture.supportedBufferFormats().isEmpty());
+
+ imageCapture.setBufferFormat(QVideoFrame::Format_AdobeDng);
+ QCOMPARE(imageCapture.bufferFormat(), QVideoFrame::Format_Invalid);
+}
+
+void tst_QCamera::testCaptureDestination()
+{
+ MockCameraService service;
+ provider->service = &service;
+ QCamera camera(0, provider);
+ QCameraImageCapture imageCapture(&camera);
+
+ QVERIFY(imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToFile));
+ QVERIFY(imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer));
+ QVERIFY(!imageCapture.isCaptureDestinationSupported(
+ QCameraImageCapture::CaptureToBuffer | QCameraImageCapture::CaptureToFile));
+
+ QSignalSpy destinationChangedSignal(&imageCapture, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)));
+
+ QCOMPARE(imageCapture.captureDestination(), QCameraImageCapture::CaptureToFile);
+ imageCapture.setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
+ QCOMPARE(imageCapture.captureDestination(), QCameraImageCapture::CaptureToBuffer);
+ QCOMPARE(destinationChangedSignal.size(), 1);
+ QCOMPARE(destinationChangedSignal.first().first().value<QCameraImageCapture::CaptureDestinations>(),
+ QCameraImageCapture::CaptureToBuffer);
+
+ //not supported combination
+ imageCapture.setCaptureDestination(QCameraImageCapture::CaptureToBuffer | QCameraImageCapture::CaptureToFile);
+ QCOMPARE(imageCapture.captureDestination(), QCameraImageCapture::CaptureToBuffer);
+ QCOMPARE(destinationChangedSignal.size(), 1);
+}
+
+void tst_QCamera::testCaptureFormat()
+{
+ MockCameraService service;
+ provider->service = &service;
+ QCamera camera(0, provider);
+ QCameraImageCapture imageCapture(&camera);
+
+ QSignalSpy formatChangedSignal(&imageCapture, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)));
+
+ QCOMPARE(imageCapture.bufferFormat(), QVideoFrame::Format_Jpeg);
+ QCOMPARE(imageCapture.supportedBufferFormats().size(), 3);
+
+ imageCapture.setBufferFormat(QVideoFrame::Format_AdobeDng);
+ QCOMPARE(imageCapture.bufferFormat(), QVideoFrame::Format_AdobeDng);
+
+ QCOMPARE(formatChangedSignal.size(), 1);
+ QCOMPARE(formatChangedSignal.first().first().value<QVideoFrame::PixelFormat>(),
+ QVideoFrame::Format_AdobeDng);
+
+ imageCapture.setBufferFormat(QVideoFrame::Format_Y16);
+ QCOMPARE(imageCapture.bufferFormat(), QVideoFrame::Format_AdobeDng);
+
+ QCOMPARE(formatChangedSignal.size(), 1);
+}
+
+
+void tst_QCamera::testCameraCapture()
+{
+ MockCameraService service;
+ provider->service = &service;
+ QCamera camera(0, provider);
+ QCameraImageCapture imageCapture(&camera);
+
+
+ QVERIFY(!imageCapture.isReadyForCapture());
+
+ QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(int,QImage)));
+ QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int, QCameraImageCapture::Error,QString)));
+
+ imageCapture.capture(QString::fromLatin1("/dev/null"));
+ QCOMPARE(capturedSignal.size(), 0);
+ QCOMPARE(errorSignal.size(), 1);
+ QCOMPARE(imageCapture.error(), QCameraImageCapture::NotReadyError);
+
+ errorSignal.clear();
+
+ camera.start();
+ QVERIFY(imageCapture.isReadyForCapture());
+ QCOMPARE(errorSignal.size(), 0);
+
+ imageCapture.capture(QString::fromLatin1("/dev/null"));
+
+ for (int i=0; i<100 && capturedSignal.isEmpty(); i++)
+ QTest::qWait(10);
+
+ QCOMPARE(capturedSignal.size(), 1);
+ QCOMPARE(errorSignal.size(), 0);
+ QCOMPARE(imageCapture.error(), QCameraImageCapture::NoError);
+}
+
+void tst_QCamera::testCameraCaptureMetadata()
+{
+ MockCameraService service;
+ provider->service = &service;
+ QCamera camera(0, provider);
+ QCameraImageCapture imageCapture(&camera);
+
+ QSignalSpy metadataSignal(&imageCapture, SIGNAL(imageMetadataAvailable(int,QtMultimediaKit::MetaData,QVariant)));
+ QSignalSpy extendedMetadataSignal(&imageCapture, SIGNAL(imageMetadataAvailable(int,QString,QVariant)));
+ QSignalSpy savedSignal(&imageCapture, SIGNAL(imageSaved(int,QString)));
+
+ camera.start();
+ int id = imageCapture.capture(QString::fromLatin1("/dev/null"));
+
+ for (int i=0; i<100 && savedSignal.isEmpty(); i++)
+ QTest::qWait(10);
+
+ QCOMPARE(savedSignal.size(), 1);
+
+ QCOMPARE(metadataSignal.size(), 2);
+
+ QVariantList metadata = metadataSignal[0];
+ QCOMPARE(metadata[0].toInt(), id);
+ QCOMPARE(metadata[1].value<QtMultimediaKit::MetaData>(), QtMultimediaKit::FocalLengthIn35mmFilm);
+ QCOMPARE(metadata[2].value<QVariant>().toInt(), 50);
+
+ metadata = metadataSignal[1];
+ QCOMPARE(metadata[0].toInt(), id);
+ QCOMPARE(metadata[1].value<QtMultimediaKit::MetaData>(), QtMultimediaKit::DateTimeOriginal);
+ QDateTime captureTime = metadata[2].value<QVariant>().value<QDateTime>();
+ QVERIFY(qAbs(captureTime.secsTo(QDateTime::currentDateTime()) < 5)); //it should not takes more than 5 seconds for signal to arrive here
+
+ QCOMPARE(extendedMetadataSignal.size(), 1);
+ metadata = extendedMetadataSignal.first();
+ QCOMPARE(metadata[0].toInt(), id);
+ QCOMPARE(metadata[1].toString(), QLatin1String("Answer to the Ultimate Question of Life, the Universe, and Everything"));
+ QCOMPARE(metadata[2].value<QVariant>().toInt(), 42);
+}
+
+
+void tst_QCamera::testCameraWhiteBalance()
+{
+ QSet<QCameraImageProcessing::WhiteBalanceMode> whiteBalanceModes;
+ whiteBalanceModes << QCameraImageProcessing::WhiteBalanceAuto;
+ whiteBalanceModes << QCameraImageProcessing::WhiteBalanceFlash;
+ whiteBalanceModes << QCameraImageProcessing::WhiteBalanceIncandescent;
+
+ MockCameraService service;
+ service.mockImageProcessingControl->setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceFlash);
+ service.mockImageProcessingControl->setSupportedWhiteBalanceModes(whiteBalanceModes);
+ service.mockImageProcessingControl->setProcessingParameter(
+ QCameraImageProcessingControl::ColorTemperature,
+ QVariant(34));
+
+ MockProvider provider;
+ provider.service = &service;
+
+ QCamera camera(0, &provider);
+ QCameraImageProcessing *cameraImageProcessing = camera.imageProcessing();
+
+ QCOMPARE(cameraImageProcessing->whiteBalanceMode(), QCameraImageProcessing::WhiteBalanceFlash);
+ QVERIFY(camera.imageProcessing()->isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceAuto));
+ QVERIFY(camera.imageProcessing()->isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceFlash));
+ QVERIFY(camera.imageProcessing()->isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceIncandescent));
+ QVERIFY(!camera.imageProcessing()->isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceCloudy));
+
+ cameraImageProcessing->setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceIncandescent);
+ QCOMPARE(cameraImageProcessing->whiteBalanceMode(), QCameraImageProcessing::WhiteBalanceIncandescent);
+
+ cameraImageProcessing->setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceManual);
+ QCOMPARE(cameraImageProcessing->whiteBalanceMode(), QCameraImageProcessing::WhiteBalanceManual);
+ QCOMPARE(cameraImageProcessing->manualWhiteBalance(), 34);
+
+ cameraImageProcessing->setManualWhiteBalance(432);
+ QCOMPARE(cameraImageProcessing->manualWhiteBalance(), 432);
+}
+
+void tst_QCamera::testCameraExposure()
+{
+ MockCameraService service;
+ provider->service = &service;
+ QCamera camera(0, provider);
+
+ QCameraExposure *cameraExposure = camera.exposure();
+ QVERIFY(cameraExposure != 0);
+
+ QVERIFY(cameraExposure->isExposureModeSupported(QCameraExposure::ExposureAuto));
+ QCOMPARE(cameraExposure->exposureMode(), QCameraExposure::ExposureAuto);
+ cameraExposure->setExposureMode(QCameraExposure::ExposureManual);
+ QCOMPARE(cameraExposure->exposureMode(), QCameraExposure::ExposureManual);
+
+ QCOMPARE(cameraExposure->flashMode(), QCameraExposure::FlashAuto);
+ QCOMPARE(cameraExposure->isFlashReady(), true);
+ cameraExposure->setFlashMode(QCameraExposure::FlashOn);
+ QCOMPARE(cameraExposure->flashMode(), QCameraExposure::FlashOn);
+
+ cameraExposure->setFlashMode(QCameraExposure::FlashRedEyeReduction); // not expected to be supported
+ QCOMPARE(cameraExposure->flashMode(), QCameraExposure::FlashOn);
+
+ QCOMPARE(cameraExposure->meteringMode(), QCameraExposure::MeteringMatrix);
+ cameraExposure->setMeteringMode(QCameraExposure::MeteringAverage);
+ QCOMPARE(cameraExposure->meteringMode(), QCameraExposure::MeteringAverage);
+ cameraExposure->setMeteringMode(QCameraExposure::MeteringSpot);
+ QCOMPARE(cameraExposure->meteringMode(), QCameraExposure::MeteringAverage);
+
+
+ QCOMPARE(cameraExposure->exposureCompensation(), 0.0);
+ cameraExposure->setExposureCompensation(2.0);
+ QCOMPARE(cameraExposure->exposureCompensation(), 2.0);
+
+ int minIso = cameraExposure->supportedIsoSensitivities().first();
+ int maxIso = cameraExposure->supportedIsoSensitivities().last();
+ QVERIFY(cameraExposure->isoSensitivity() > 0);
+ QVERIFY(minIso > 0);
+ QVERIFY(maxIso > 0);
+ cameraExposure->setManualIsoSensitivity(minIso);
+ QCOMPARE(cameraExposure->isoSensitivity(), minIso);
+ cameraExposure->setManualIsoSensitivity(maxIso*10);
+ QCOMPARE(cameraExposure->isoSensitivity(), maxIso);
+ cameraExposure->setManualIsoSensitivity(-10);
+ QCOMPARE(cameraExposure->isoSensitivity(), minIso);
+ cameraExposure->setAutoIsoSensitivity();
+ QCOMPARE(cameraExposure->isoSensitivity(), 100);
+
+ qreal minAperture = cameraExposure->supportedApertures().first();
+ qreal maxAperture = cameraExposure->supportedApertures().last();
+ QVERIFY(minAperture > 0);
+ QVERIFY(maxAperture > 0);
+ QVERIFY(cameraExposure->aperture() >= minAperture);
+ QVERIFY(cameraExposure->aperture() <= maxAperture);
+
+ cameraExposure->setAutoAperture();
+ QVERIFY(cameraExposure->aperture() >= minAperture);
+ QVERIFY(cameraExposure->aperture() <= maxAperture);
+
+ cameraExposure->setManualAperture(0);
+ QCOMPARE(cameraExposure->aperture(), minAperture);
+
+ cameraExposure->setManualAperture(10000);
+ QCOMPARE(cameraExposure->aperture(), maxAperture);
+
+
+ qreal minShutterSpeed = cameraExposure->supportedShutterSpeeds().first();
+ qreal maxShutterSpeed = cameraExposure->supportedShutterSpeeds().last();
+ QVERIFY(minShutterSpeed > 0);
+ QVERIFY(maxShutterSpeed > 0);
+ QVERIFY(cameraExposure->shutterSpeed() >= minShutterSpeed);
+ QVERIFY(cameraExposure->shutterSpeed() <= maxShutterSpeed);
+
+ cameraExposure->setAutoShutterSpeed();
+ QVERIFY(cameraExposure->shutterSpeed() >= minShutterSpeed);
+ QVERIFY(cameraExposure->shutterSpeed() <= maxShutterSpeed);
+
+ cameraExposure->setManualShutterSpeed(0);
+ QCOMPARE(cameraExposure->shutterSpeed(), minShutterSpeed);
+
+ cameraExposure->setManualShutterSpeed(10000);
+ QCOMPARE(cameraExposure->shutterSpeed(), maxShutterSpeed);
+}
+
+void tst_QCamera::testCameraFocus()
+{
+ MockCameraService service;
+ provider->service = &service;
+ QCamera camera(0, provider);
+
+ QCameraFocus *cameraFocus = camera.focus();
+ QVERIFY(cameraFocus != 0);
+
+ QVERIFY(cameraFocus->isFocusModeSupported(QCameraFocus::AutoFocus));
+ QVERIFY(cameraFocus->isFocusModeSupported(QCameraFocus::ContinuousFocus));
+ QVERIFY(!cameraFocus->isFocusModeSupported(QCameraFocus::InfinityFocus));
+
+ QCOMPARE(cameraFocus->focusMode(), QCameraFocus::AutoFocus);
+ cameraFocus->setFocusMode(QCameraFocus::ManualFocus);
+ QCOMPARE(cameraFocus->focusMode(), QCameraFocus::AutoFocus);
+ cameraFocus->setFocusMode(QCameraFocus::ContinuousFocus);
+ QCOMPARE(cameraFocus->focusMode(), QCameraFocus::ContinuousFocus);
+
+ QVERIFY(cameraFocus->maximumOpticalZoom() >= 1.0);
+ QVERIFY(cameraFocus->maximumDigitalZoom() >= 1.0);
+ QCOMPARE(cameraFocus->opticalZoom(), 1.0);
+ QCOMPARE(cameraFocus->digitalZoom(), 1.0);
+ cameraFocus->zoomTo(0.5, 1.0);
+ QCOMPARE(cameraFocus->opticalZoom(), 1.0);
+ QCOMPARE(cameraFocus->digitalZoom(), 1.0);
+ cameraFocus->zoomTo(2.0, 0.5);
+ QCOMPARE(cameraFocus->opticalZoom(), 2.0);
+ QCOMPARE(cameraFocus->digitalZoom(), 1.0);
+ cameraFocus->zoomTo(2.0, 2.5);
+ QCOMPARE(cameraFocus->opticalZoom(), 2.0);
+ QCOMPARE(cameraFocus->digitalZoom(), 2.5);
+ cameraFocus->zoomTo(2000000.0, 1000000.0);
+ QVERIFY(qFuzzyCompare(cameraFocus->opticalZoom(), cameraFocus->maximumOpticalZoom()));
+ QVERIFY(qFuzzyCompare(cameraFocus->digitalZoom(), cameraFocus->maximumDigitalZoom()));
+
+ QVERIFY(cameraFocus->isFocusPointModeSupported(QCameraFocus::FocusPointAuto));
+ QVERIFY(cameraFocus->isFocusPointModeSupported(QCameraFocus::FocusPointCenter));
+ QVERIFY(cameraFocus->isFocusPointModeSupported(QCameraFocus::FocusPointCustom));
+ QCOMPARE(cameraFocus->focusPointMode(), QCameraFocus::FocusPointAuto);
+
+ cameraFocus->setFocusPointMode( QCameraFocus::FocusPointCenter );
+ QCOMPARE(cameraFocus->focusPointMode(), QCameraFocus::FocusPointCenter);
+
+ cameraFocus->setFocusPointMode( QCameraFocus::FocusPointFaceDetection );
+ QCOMPARE(cameraFocus->focusPointMode(), QCameraFocus::FocusPointCenter);
+
+ QCOMPARE(cameraFocus->customFocusPoint(), QPointF(0.5, 0.5));
+ cameraFocus->setCustomFocusPoint(QPointF(1.0, 1.0));
+ QCOMPARE(cameraFocus->customFocusPoint(), QPointF(1.0, 1.0));
+}
+
+void tst_QCamera::testImageSettings()
+{
+ QImageEncoderSettings settings;
+ QVERIFY(settings.isNull());
+ QVERIFY(settings == QImageEncoderSettings());
+
+ QCOMPARE(settings.codec(), QString());
+ settings.setCodec(QLatin1String("codecName"));
+ QCOMPARE(settings.codec(), QLatin1String("codecName"));
+ QVERIFY(!settings.isNull());
+ QVERIFY(settings != QImageEncoderSettings());
+
+ settings = QImageEncoderSettings();
+ QCOMPARE(settings.quality(), QtMultimediaKit::NormalQuality);
+ settings.setQuality(QtMultimediaKit::HighQuality);
+ QCOMPARE(settings.quality(), QtMultimediaKit::HighQuality);
+ QVERIFY(!settings.isNull());
+
+ settings = QImageEncoderSettings();
+ QCOMPARE(settings.resolution(), QSize());
+ settings.setResolution(QSize(320,240));
+ QCOMPARE(settings.resolution(), QSize(320,240));
+ settings.setResolution(800,600);
+ QCOMPARE(settings.resolution(), QSize(800,600));
+ QVERIFY(!settings.isNull());
+
+ settings = QImageEncoderSettings();
+ QVERIFY(settings.isNull());
+ QCOMPARE(settings.codec(), QString());
+ QCOMPARE(settings.quality(), QtMultimediaKit::NormalQuality);
+ QCOMPARE(settings.resolution(), QSize());
+
+ {
+ QImageEncoderSettings settings1;
+ QImageEncoderSettings settings2;
+ QCOMPARE(settings2, settings1);
+
+ settings2 = settings1;
+ QCOMPARE(settings2, settings1);
+ QVERIFY(settings2.isNull());
+
+ settings1.setQuality(QtMultimediaKit::HighQuality);
+
+ QVERIFY(settings2.isNull());
+ QVERIFY(!settings1.isNull());
+ QVERIFY(settings1 != settings2);
+ }
+
+ {
+ QImageEncoderSettings settings1;
+ QImageEncoderSettings settings2(settings1);
+ QCOMPARE(settings2, settings1);
+
+ settings2 = settings1;
+ QCOMPARE(settings2, settings1);
+ QVERIFY(settings2.isNull());
+
+ settings1.setQuality(QtMultimediaKit::HighQuality);
+
+ QVERIFY(settings2.isNull());
+ QVERIFY(!settings1.isNull());
+ QVERIFY(settings1 != settings2);
+ }
+
+ QImageEncoderSettings settings1;
+ QImageEncoderSettings settings2;
+
+ settings1 = QImageEncoderSettings();
+ settings1.setResolution(800,600);
+ settings2 = QImageEncoderSettings();
+ settings2.setResolution(QSize(800,600));
+ QVERIFY(settings1 == settings2);
+ settings2.setResolution(QSize(400,300));
+ QVERIFY(settings1 != settings2);
+
+ settings1 = QImageEncoderSettings();
+ settings1.setCodec("codec1");
+ settings2 = QImageEncoderSettings();
+ settings2.setCodec("codec1");
+ QVERIFY(settings1 == settings2);
+ settings2.setCodec("codec2");
+ QVERIFY(settings1 != settings2);
+
+ settings1 = QImageEncoderSettings();
+ settings1.setQuality(QtMultimediaKit::NormalQuality);
+ settings2 = QImageEncoderSettings();
+ settings2.setQuality(QtMultimediaKit::NormalQuality);
+ QVERIFY(settings1 == settings2);
+ settings2.setQuality(QtMultimediaKit::LowQuality);
+ QVERIFY(settings1 != settings2);
+}
+
+void tst_QCamera::testCameraLock()
+{
+ MockCameraService service;
+ provider->service = &service;
+ QCamera camera(0, provider);
+
+ camera.focus()->setFocusMode(QCameraFocus::AutoFocus);
+
+ QCOMPARE(camera.lockStatus(), QCamera::Unlocked);
+
+ QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
+ QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
+ QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)));
+
+ camera.searchAndLock();
+ QCOMPARE(camera.lockStatus(), QCamera::Searching);
+ QCOMPARE(lockedSignal.count(), 0);
+ QCOMPARE(lockFailedSignal.count(), 0);
+ QCOMPARE(lockStatusChangedSignal.count(), 1);
+
+ lockedSignal.clear();
+ lockFailedSignal.clear();
+ lockStatusChangedSignal.clear();
+
+ for (int i=0; i<200 && camera.lockStatus() == QCamera::Searching; i++)
+ QTest::qWait(10);
+
+ QCOMPARE(camera.lockStatus(), QCamera::Locked);
+ QCOMPARE(lockedSignal.count(), 1);
+ QCOMPARE(lockFailedSignal.count(), 0);
+ QCOMPARE(lockStatusChangedSignal.count(), 1);
+
+ lockedSignal.clear();
+ lockFailedSignal.clear();
+ lockStatusChangedSignal.clear();
+
+ camera.searchAndLock();
+ QCOMPARE(camera.lockStatus(), QCamera::Searching);
+ QCOMPARE(lockedSignal.count(), 0);
+ QCOMPARE(lockFailedSignal.count(), 0);
+ QCOMPARE(lockStatusChangedSignal.count(), 1);
+
+ lockedSignal.clear();
+ lockFailedSignal.clear();
+ lockStatusChangedSignal.clear();
+
+ camera.unlock();
+ QCOMPARE(camera.lockStatus(), QCamera::Unlocked);
+ QCOMPARE(lockedSignal.count(), 0);
+ QCOMPARE(lockFailedSignal.count(), 0);
+ QCOMPARE(lockStatusChangedSignal.count(), 1);
+}
+
+void tst_QCamera::testCameraLockCancel()
+{
+ MockCameraService service;
+ provider->service = &service;
+ QCamera camera(0, provider);
+
+ camera.focus()->setFocusMode(QCameraFocus::AutoFocus);
+
+ QCOMPARE(camera.lockStatus(), QCamera::Unlocked);
+
+ QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
+ QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
+ QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
+ camera.searchAndLock();
+ QCOMPARE(camera.lockStatus(), QCamera::Searching);
+ QCOMPARE(lockedSignal.count(), 0);
+ QCOMPARE(lockFailedSignal.count(), 0);
+ QCOMPARE(lockStatusChangedSignal.count(), 1);
+
+ lockedSignal.clear();
+ lockFailedSignal.clear();
+ lockStatusChangedSignal.clear();
+
+ camera.unlock();
+ QCOMPARE(camera.lockStatus(), QCamera::Unlocked);
+ QCOMPARE(lockedSignal.count(), 0);
+ QCOMPARE(lockFailedSignal.count(), 0);
+ QCOMPARE(lockStatusChangedSignal.count(), 1);
+}
+
+void tst_QCamera::testCameraEncodingProperyChange()
+{
+ MockCameraService service;
+ provider->service = &service;
+ QCamera camera(0, provider);
+ QCameraImageCapture imageCapture(&camera);
+
+ QSignalSpy stateChangedSignal(&camera, SIGNAL(stateChanged(QCamera::State)));
+ QSignalSpy statusChangedSignal(&camera, SIGNAL(statusChanged(QCamera::Status)));
+
+ camera.start();
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ QCOMPARE(camera.status(), QCamera::ActiveStatus);
+
+ QCOMPARE(stateChangedSignal.count(), 1);
+ QCOMPARE(statusChangedSignal.count(), 1);
+ stateChangedSignal.clear();
+ statusChangedSignal.clear();
+
+ camera.setCaptureMode(QCamera::CaptureVideo);
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ QCOMPARE(camera.status(), QCamera::LoadedStatus);
+
+ QCOMPARE(stateChangedSignal.count(), 0);
+ QCOMPARE(statusChangedSignal.count(), 1);
+ stateChangedSignal.clear();
+ statusChangedSignal.clear();
+
+ QTest::qWait(10);
+
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ QCOMPARE(camera.status(), QCamera::ActiveStatus);
+ QCOMPARE(stateChangedSignal.count(), 0);
+ QCOMPARE(statusChangedSignal.count(), 1);
+ stateChangedSignal.clear();
+ statusChangedSignal.clear();
+
+ //backens should not be stopped since the capture mode is Video
+ imageCapture.setEncodingSettings(QImageEncoderSettings());
+ QCOMPARE(stateChangedSignal.count(), 0);
+ QCOMPARE(statusChangedSignal.count(), 0);
+
+ camera.setCaptureMode(QCamera::CaptureStillImage);
+ QTest::qWait(10);
+ stateChangedSignal.clear();
+ statusChangedSignal.clear();
+
+ //the settings change should trigger camera stop/start
+ imageCapture.setEncodingSettings(QImageEncoderSettings());
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ QCOMPARE(camera.status(), QCamera::LoadedStatus);
+
+ QCOMPARE(stateChangedSignal.count(), 0);
+ QCOMPARE(statusChangedSignal.count(), 1);
+ stateChangedSignal.clear();
+ statusChangedSignal.clear();
+
+ QTest::qWait(10);
+
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ QCOMPARE(camera.status(), QCamera::ActiveStatus);
+ QCOMPARE(stateChangedSignal.count(), 0);
+ QCOMPARE(statusChangedSignal.count(), 1);
+ stateChangedSignal.clear();
+ statusChangedSignal.clear();
+
+ //the settings change should trigger camera stop/start only once
+ camera.setCaptureMode(QCamera::CaptureVideo);
+ camera.setCaptureMode(QCamera::CaptureStillImage);
+ imageCapture.setEncodingSettings(QImageEncoderSettings());
+ imageCapture.setEncodingSettings(QImageEncoderSettings());
+
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ QCOMPARE(camera.status(), QCamera::LoadedStatus);
+
+ QCOMPARE(stateChangedSignal.count(), 0);
+ QCOMPARE(statusChangedSignal.count(), 1);
+ stateChangedSignal.clear();
+ statusChangedSignal.clear();
+
+ QTest::qWait(10);
+
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ QCOMPARE(camera.status(), QCamera::ActiveStatus);
+ QCOMPARE(stateChangedSignal.count(), 0);
+ QCOMPARE(statusChangedSignal.count(), 1);
+ stateChangedSignal.clear();
+ statusChangedSignal.clear();
+
+ //setting the viewfinder should also trigget backend to be restarted:
+ camera.setViewfinder(new QGraphicsVideoItem());
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ QCOMPARE(camera.status(), QCamera::LoadedStatus);
+
+ QCOMPARE(stateChangedSignal.count(), 0);
+ QCOMPARE(statusChangedSignal.count(), 1);
+
+ QTest::qWait(10);
+
+ service.mockControl->m_propertyChangesSupported = true;
+ //the changes to encoding settings,
+ //capture mode and encoding parameters should not trigger service restart
+ stateChangedSignal.clear();
+ statusChangedSignal.clear();
+
+ camera.setCaptureMode(QCamera::CaptureVideo);
+ camera.setCaptureMode(QCamera::CaptureStillImage);
+ imageCapture.setEncodingSettings(QImageEncoderSettings());
+ imageCapture.setEncodingSettings(QImageEncoderSettings());
+ camera.setViewfinder(new QGraphicsVideoItem());
+
+ QCOMPARE(stateChangedSignal.count(), 0);
+ QCOMPARE(statusChangedSignal.count(), 0);
+
+}
+
+void tst_QCamera::testSetVideoOutput()
+{
+ QVideoWidget widget;
+ QGraphicsVideoItem item;
+ MockVideoSurface surface;
+
+ MockCameraService service;
+ MockProvider provider;
+ provider.service = &service;
+ QCamera camera(0, &provider);
+
+ camera.setViewfinder(&widget);
+ QVERIFY(widget.mediaObject() == &camera);
+
+ camera.setViewfinder(&item);
+ QVERIFY(widget.mediaObject() == 0);
+ QVERIFY(item.mediaObject() == &camera);
+
+ camera.setViewfinder(reinterpret_cast<QVideoWidget *>(0));
+ QVERIFY(item.mediaObject() == 0);
+
+ camera.setViewfinder(&widget);
+ QVERIFY(widget.mediaObject() == &camera);
+
+ camera.setViewfinder(reinterpret_cast<QGraphicsVideoItem *>(0));
+ QVERIFY(widget.mediaObject() == 0);
+
+ camera.setViewfinder(&surface);
+ QVERIFY(service.rendererControl->surface() == &surface);
+
+ camera.setViewfinder(reinterpret_cast<QAbstractVideoSurface *>(0));
+ QVERIFY(service.rendererControl->surface() == 0);
+
+ camera.setViewfinder(&surface);
+ QVERIFY(service.rendererControl->surface() == &surface);
+
+ camera.setViewfinder(&widget);
+ QVERIFY(service.rendererControl->surface() == 0);
+ QVERIFY(widget.mediaObject() == &camera);
+
+ camera.setViewfinder(&surface);
+ QVERIFY(service.rendererControl->surface() == &surface);
+ QVERIFY(widget.mediaObject() == 0);
+}
+
+
+void tst_QCamera::testSetVideoOutputNoService()
+{
+ QVideoWidget widget;
+ QGraphicsVideoItem item;
+ MockVideoSurface surface;
+
+ MockProvider provider;
+ provider.service = 0;
+ QCamera camera(0, &provider);
+
+ camera.setViewfinder(&widget);
+ QVERIFY(widget.mediaObject() == 0);
+
+ camera.setViewfinder(&item);
+ QVERIFY(item.mediaObject() == 0);
+
+ camera.setViewfinder(&surface);
+ // Nothing we can verify here other than it doesn't assert.
+}
+
+void tst_QCamera::testSetVideoOutputNoControl()
+{
+ QVideoWidget widget;
+ QGraphicsVideoItem item;
+ MockVideoSurface surface;
+
+ MockCameraService service;
+ service.rendererRef = 1;
+ service.windowRef = 1;
+
+ MockProvider provider;
+ provider.service = &service;
+ QCamera camera(0, &provider);
+
+ camera.setViewfinder(&widget);
+ QVERIFY(widget.mediaObject() == 0);
+
+ camera.setViewfinder(&item);
+ QVERIFY(item.mediaObject() == 0);
+
+ camera.setViewfinder(&surface);
+ QVERIFY(service.rendererControl->surface() == 0);
+}
+
+void tst_QCamera::testSetVideoOutputDestruction()
+{
+ MockVideoSurface surface;
+
+ MockCameraService service;
+ MockProvider provider;
+ provider.service = &service;
+
+ {
+ QCamera camera(0, &provider);
+ camera.setViewfinder(&surface);
+ QVERIFY(service.rendererControl->surface() == &surface);
+ QCOMPARE(service.rendererRef, 1);
+ }
+ QVERIFY(service.rendererControl->surface() == 0);
+ QCOMPARE(service.rendererRef, 0);
+}
+
+void tst_QCamera::testEnumDebug()
+{
+ QTest::ignoreMessage(QtDebugMsg, "QCamera::ActiveState ");
+ qDebug() << QCamera::ActiveState;
+ QTest::ignoreMessage(QtDebugMsg, "QCamera::ActiveStatus ");
+ qDebug() << QCamera::ActiveStatus;
+ QTest::ignoreMessage(QtDebugMsg, "QCamera::CaptureVideo ");
+ qDebug() << QCamera::CaptureVideo;
+ QTest::ignoreMessage(QtDebugMsg, "QCamera::CameraError ");
+ qDebug() << QCamera::CameraError;
+ QTest::ignoreMessage(QtDebugMsg, "QCamera::Unlocked ");
+ qDebug() << QCamera::Unlocked;
+ QTest::ignoreMessage(QtDebugMsg, "QCamera::LockAcquired ");
+ qDebug() << QCamera::LockAcquired;
+ QTest::ignoreMessage(QtDebugMsg, "QCamera::NoLock ");
+ qDebug() << QCamera::NoLock;
+ QTest::ignoreMessage(QtDebugMsg, "QCamera::LockExposure ");
+ qDebug() << QCamera::LockExposure;
+}
+
+QTEST_MAIN(tst_QCamera)
+
+#include "tst_qcamera.moc"
diff --git a/tests/auto/qcamerabackend/qcamerabackend.pro b/tests/auto/qcamerabackend/qcamerabackend.pro
new file mode 100644
index 000000000..80e853d8b
--- /dev/null
+++ b/tests/auto/qcamerabackend/qcamerabackend.pro
@@ -0,0 +1,15 @@
+load(qttest_p4)
+
+QT += multimediakit-private
+
+# TARGET = tst_qcamerabackend
+# CONFIG += testcase
+
+SOURCES += tst_qcamerabackend.cpp
+
+symbian {
+ TARGET.CAPABILITY = ALL -TCB
+ TARGET.EPOCHEAPSIZE = 0x20000 0x3000000
+}
+
+maemo*:CONFIG += insignificant_test
diff --git a/tests/auto/qcamerabackend/tst_qcamerabackend.cpp b/tests/auto/qcamerabackend/tst_qcamerabackend.cpp
new file mode 100644
index 000000000..3fe3c7520
--- /dev/null
+++ b/tests/auto/qcamerabackend/tst_qcamerabackend.cpp
@@ -0,0 +1,633 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include <QtTest/QtTest>
+#include <QtGui/QImageReader>
+#include <QDebug>
+
+#include <qabstractvideosurface.h>
+#include <qcameracontrol.h>
+#include <qcameralockscontrol.h>
+#include <qcameraexposurecontrol.h>
+#include <qcameraflashcontrol.h>
+#include <qcamerafocuscontrol.h>
+#include <qcameraimagecapturecontrol.h>
+#include <qimageencodercontrol.h>
+#include <qcameraimageprocessingcontrol.h>
+#include <qcameracapturebufferformatcontrol.h>
+#include <qcameracapturedestinationcontrol.h>
+#include <qmediaservice.h>
+#include <qcamera.h>
+#include <qcameraimagecapture.h>
+#include <qgraphicsvideoitem.h>
+#include <qvideorenderercontrol.h>
+#include <qvideowidget.h>
+#include <qvideowindowcontrol.h>
+
+QT_USE_NAMESPACE
+
+// Eventually these will make it into qtestcase.h
+// but we might need to tweak the timeout values here.
+#ifndef QTRY_COMPARE
+#define QTRY_COMPARE(__expr, __expected) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 10000; \
+ if ((__expr) != (__expected)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ QCOMPARE(__expr, __expected); \
+ } while(0)
+#endif
+
+#ifndef QTRY_VERIFY
+#define QTRY_VERIFY(__expr) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 10000; \
+ if (!(__expr)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ QVERIFY(__expr); \
+ } while(0)
+#endif
+
+
+#define QTRY_WAIT(code, __expr) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 10000; \
+ if (!(__expr)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
+ do { code } while(0); \
+ QTest::qWait(__step); \
+ } \
+ } while(0)
+
+
+/*
+ This is the backend conformance test.
+
+ Since it relies on platform media framework and sound hardware
+ it may be less stable.
+*/
+
+
+Q_DECLARE_METATYPE(QtMultimediaKit::MetaData)
+Q_DECLARE_METATYPE(QVideoFrame)
+
+class tst_QCameraBackend: public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ void testAvailableDevices();
+ void testDeviceDescription();
+ void testCtorWithDevice();
+
+ void testCameraStates();
+ void testCaptureMode();
+ void testCameraCapture();
+ void testCaptureToBuffer();
+ void testCameraCaptureMetadata();
+ void testExposureCompensation();
+ void testExposureMode();
+private:
+};
+
+void tst_QCameraBackend::initTestCase()
+{
+ qRegisterMetaType<QtMultimediaKit::MetaData>("QtMultimediaKit::MetaData");
+
+ QCamera camera;
+ if (!camera.isAvailable())
+ QSKIP("Camera is not available", SkipAll);
+}
+
+void tst_QCameraBackend::cleanupTestCase()
+{
+}
+
+void tst_QCameraBackend::testAvailableDevices()
+{
+ int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();
+ QCOMPARE(QCamera::availableDevices().count(), deviceCount);
+}
+
+void tst_QCameraBackend::testDeviceDescription()
+{
+ int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();
+
+ if (deviceCount == 0)
+ QVERIFY(QCamera::deviceDescription(QByteArray("random")).isNull());
+ else {
+ foreach (const QByteArray &device, QCamera::availableDevices())
+ QVERIFY(QCamera::deviceDescription(device).length() > 0);
+ }
+}
+
+void tst_QCameraBackend::testCtorWithDevice()
+{
+ int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();
+ QCamera *camera = 0;
+
+ if (deviceCount == 0) {
+ camera = new QCamera("random");
+ QCOMPARE(camera->error(), QCamera::ServiceMissingError);
+ }
+ else {
+ camera = new QCamera(QCamera::availableDevices().first());
+ QCOMPARE(camera->error(), QCamera::NoError);
+ }
+
+ delete camera;
+}
+
+void tst_QCameraBackend::testCameraStates()
+{
+ QCamera camera;
+ QCameraImageCapture imageCapture(&camera);
+
+ QSignalSpy errorSignal(&camera, SIGNAL(error(QCamera::Error)));
+ QSignalSpy stateChangedSignal(&camera, SIGNAL(stateChanged(QCamera::State)));
+ QSignalSpy statusChangedSignal(&camera, SIGNAL(statusChanged(QCamera::Status)));
+
+ QCOMPARE(camera.state(), QCamera::UnloadedState);
+ QCOMPARE(camera.status(), QCamera::UnloadedStatus);
+
+ camera.load();
+ QCOMPARE(camera.state(), QCamera::LoadedState);
+ QCOMPARE(stateChangedSignal.count(), 1);
+ QCOMPARE(stateChangedSignal.last().first().value<QCamera::State>(), QCamera::LoadedState);
+ QVERIFY(stateChangedSignal.count() > 0);
+
+ QTRY_COMPARE(camera.status(), QCamera::LoadedStatus);
+ QCOMPARE(statusChangedSignal.last().first().value<QCamera::Status>(), QCamera::LoadedStatus);
+
+ camera.unload();
+ QCOMPARE(camera.state(), QCamera::UnloadedState);
+ QCOMPARE(stateChangedSignal.last().first().value<QCamera::State>(), QCamera::UnloadedState);
+ QTRY_COMPARE(camera.status(), QCamera::UnloadedStatus);
+ QCOMPARE(statusChangedSignal.last().first().value<QCamera::Status>(), QCamera::UnloadedStatus);
+
+ camera.start();
+ QCOMPARE(camera.state(), QCamera::ActiveState);
+ QCOMPARE(stateChangedSignal.last().first().value<QCamera::State>(), QCamera::ActiveState);
+ QTRY_COMPARE(camera.status(), QCamera::ActiveStatus);
+ QCOMPARE(statusChangedSignal.last().first().value<QCamera::Status>(), QCamera::ActiveStatus);
+
+ camera.stop();
+ QCOMPARE(camera.state(), QCamera::LoadedState);
+ QCOMPARE(stateChangedSignal.last().first().value<QCamera::State>(), QCamera::LoadedState);
+ QTRY_COMPARE(camera.status(), QCamera::LoadedStatus);
+ QCOMPARE(statusChangedSignal.last().first().value<QCamera::Status>(), QCamera::LoadedStatus);
+
+ camera.unload();
+ QCOMPARE(camera.state(), QCamera::UnloadedState);
+ QCOMPARE(stateChangedSignal.last().first().value<QCamera::State>(), QCamera::UnloadedState);
+ QTRY_COMPARE(camera.status(), QCamera::UnloadedStatus);
+ QCOMPARE(statusChangedSignal.last().first().value<QCamera::Status>(), QCamera::UnloadedStatus);
+
+ QCOMPARE(camera.errorString(), QString());
+ QCOMPARE(errorSignal.count(), 0);
+}
+
+void tst_QCameraBackend::testCaptureMode()
+{
+ QCamera camera;
+
+ QSignalSpy errorSignal(&camera, SIGNAL(error(QCamera::Error)));
+ QSignalSpy stateChangedSignal(&camera, SIGNAL(stateChanged(QCamera::State)));
+ QSignalSpy captureModeSignal(&camera, SIGNAL(captureModeChanged(QCamera::CaptureMode)));
+
+ QCOMPARE(camera.captureMode(), QCamera::CaptureStillImage);
+
+ if (!camera.isCaptureModeSupported(QCamera::CaptureVideo)) {
+ camera.setCaptureMode(QCamera::CaptureVideo);
+ QCOMPARE(camera.captureMode(), QCamera::CaptureStillImage);
+ QSKIP("Video capture not supported", SkipAll);
+ }
+
+ camera.setCaptureMode(QCamera::CaptureVideo);
+ QCOMPARE(camera.captureMode(), QCamera::CaptureVideo);
+ QTRY_COMPARE(captureModeSignal.size(), 1);
+ QCOMPARE(captureModeSignal.last().first().value<QCamera::CaptureMode>(), QCamera::CaptureVideo);
+ captureModeSignal.clear();
+
+ camera.load();
+ QTRY_COMPARE(camera.status(), QCamera::LoadedStatus);
+ //capture mode should still be video
+ QCOMPARE(camera.captureMode(), QCamera::CaptureVideo);
+
+ //it should be possible to switch capture mode in Loaded state
+ camera.setCaptureMode(QCamera::CaptureStillImage);
+ QTRY_COMPARE(captureModeSignal.size(), 1);
+ QCOMPARE(captureModeSignal.last().first().value<QCamera::CaptureMode>(), QCamera::CaptureStillImage);
+ captureModeSignal.clear();
+
+ camera.setCaptureMode(QCamera::CaptureVideo);
+ QTRY_COMPARE(captureModeSignal.size(), 1);
+ QCOMPARE(captureModeSignal.last().first().value<QCamera::CaptureMode>(), QCamera::CaptureVideo);
+ captureModeSignal.clear();
+
+ camera.start();
+ QTRY_COMPARE(camera.status(), QCamera::ActiveStatus);
+ //capture mode should still be video
+ QCOMPARE(camera.captureMode(), QCamera::CaptureVideo);
+
+ stateChangedSignal.clear();
+ //it should be possible to switch capture mode in Active state
+ camera.setCaptureMode(QCamera::CaptureStillImage);
+ //camera may leave Active status, but should return to Active
+ QTest::qWait(10); //camera may leave Active status async
+ QTRY_COMPARE(camera.status(), QCamera::ActiveStatus);
+ QCOMPARE(camera.captureMode(), QCamera::CaptureStillImage);
+ QVERIFY2(stateChangedSignal.isEmpty(), "camera should not change the state during capture mode changes");
+
+ QCOMPARE(captureModeSignal.size(), 1);
+ QCOMPARE(captureModeSignal.last().first().value<QCamera::CaptureMode>(), QCamera::CaptureStillImage);
+ captureModeSignal.clear();
+
+ camera.setCaptureMode(QCamera::CaptureVideo);
+ //camera may leave Active status, but should return to Active
+ QTest::qWait(10); //camera may leave Active status async
+ QTRY_COMPARE(camera.status(), QCamera::ActiveStatus);
+ QCOMPARE(camera.captureMode(), QCamera::CaptureVideo);
+
+ QVERIFY2(stateChangedSignal.isEmpty(), "camera should not change the state during capture mode changes");
+
+ QCOMPARE(captureModeSignal.size(), 1);
+ QCOMPARE(captureModeSignal.last().first().value<QCamera::CaptureMode>(), QCamera::CaptureVideo);
+ captureModeSignal.clear();
+
+ camera.stop();
+ QCOMPARE(camera.captureMode(), QCamera::CaptureVideo);
+ camera.unload();
+ QCOMPARE(camera.captureMode(), QCamera::CaptureVideo);
+
+ QVERIFY2(errorSignal.isEmpty(), QString("Camera error: %1").arg(camera.errorString()).toLocal8Bit());
+}
+
+void tst_QCameraBackend::testCameraCapture()
+{
+ QCamera camera;
+ QCameraImageCapture imageCapture(&camera);
+ //prevents camera to flash during the test
+ camera.exposure()->setFlashMode(QCameraExposure::FlashOff);
+
+ QVERIFY(!imageCapture.isReadyForCapture());
+
+ QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(int,QImage)));
+ QSignalSpy savedSignal(&imageCapture, SIGNAL(imageSaved(int,QString)));
+ QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int, QCameraImageCapture::Error,QString)));
+
+ imageCapture.capture();
+ QTRY_COMPARE(errorSignal.size(), 1);
+ QCOMPARE(imageCapture.error(), QCameraImageCapture::NotReadyError);
+ QCOMPARE(capturedSignal.size(), 0);
+ errorSignal.clear();
+
+ camera.start();
+
+ QTRY_VERIFY(imageCapture.isReadyForCapture());
+ QCOMPARE(camera.status(), QCamera::ActiveStatus);
+ QCOMPARE(errorSignal.size(), 0);
+
+ int id = imageCapture.capture();
+
+ QTRY_VERIFY(!savedSignal.isEmpty());
+
+ QCOMPARE(capturedSignal.size(), 1);
+ QCOMPARE(capturedSignal.last().first().toInt(), id);
+ QCOMPARE(errorSignal.size(), 0);
+ QCOMPARE(imageCapture.error(), QCameraImageCapture::NoError);
+
+ QCOMPARE(savedSignal.last().first().toInt(), id);
+ QString location = savedSignal.last().last().toString();
+ QVERIFY(!location.isEmpty());
+ QVERIFY(QFileInfo(location).exists());
+ QImageReader reader(location);
+ reader.setScaledSize(QSize(320,240));
+ QVERIFY(!reader.read().isNull());
+
+ QFile(location).remove();
+}
+
+
+void tst_QCameraBackend::testCaptureToBuffer()
+{
+ QCamera camera;
+ QCameraImageCapture imageCapture(&camera);
+ camera.exposure()->setFlashMode(QCameraExposure::FlashOff);
+
+ camera.load();
+
+#ifdef Q_WS_MAEMO_6
+ QVERIFY(imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer));
+#endif
+
+ if (!imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer))
+ QSKIP("Buffer capture not supported", SkipAll);
+
+ QTRY_COMPARE(camera.status(), QCamera::LoadedStatus);
+
+ QCOMPARE(imageCapture.bufferFormat(), QVideoFrame::Format_Jpeg);
+
+ QVERIFY(imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToFile));
+ QVERIFY(imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer));
+ QVERIFY(imageCapture.isCaptureDestinationSupported(
+ QCameraImageCapture::CaptureToBuffer | QCameraImageCapture::CaptureToFile));
+
+ QSignalSpy destinationChangedSignal(&imageCapture, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)));
+
+ QCOMPARE(imageCapture.captureDestination(), QCameraImageCapture::CaptureToFile);
+ imageCapture.setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
+ QCOMPARE(imageCapture.captureDestination(), QCameraImageCapture::CaptureToBuffer);
+ QCOMPARE(destinationChangedSignal.size(), 1);
+ QCOMPARE(destinationChangedSignal.first().first().value<QCameraImageCapture::CaptureDestinations>(),
+ QCameraImageCapture::CaptureToBuffer);
+
+ QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(int,QImage)));
+ QSignalSpy imageAvailableSignal(&imageCapture, SIGNAL(imageAvailable(int,QVideoFrame)));
+ QSignalSpy savedSignal(&imageCapture, SIGNAL(imageSaved(int,QString)));
+ QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int, QCameraImageCapture::Error,QString)));
+
+ camera.start();
+ QTRY_VERIFY(imageCapture.isReadyForCapture());
+
+ int id = imageCapture.capture();
+ QTRY_VERIFY(!imageAvailableSignal.isEmpty());
+
+ QVERIFY(errorSignal.isEmpty());
+ QVERIFY(!capturedSignal.isEmpty());
+ QVERIFY(!imageAvailableSignal.isEmpty());
+
+ QTest::qWait(2000);
+ QVERIFY(savedSignal.isEmpty());
+
+ QCOMPARE(capturedSignal.first().first().toInt(), id);
+ QCOMPARE(imageAvailableSignal.first().first().toInt(), id);
+
+ QVideoFrame frame = imageAvailableSignal.first().last().value<QVideoFrame>();
+ QVERIFY(frame.isValid());
+ QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_Jpeg);
+ QVERIFY(!frame.size().isEmpty());
+ QVERIFY(frame.map(QAbstractVideoBuffer::ReadOnly));
+ QByteArray data((const char *)frame.bits(), frame.mappedBytes());
+ frame.unmap();
+ frame = QVideoFrame();
+
+ QVERIFY(!data.isEmpty());
+ QBuffer buffer;
+ buffer.setData(data);
+ buffer.open(QIODevice::ReadOnly);
+ QImageReader reader(&buffer, "JPG");
+ reader.setScaledSize(QSize(640,480));
+ QImage img(reader.read());
+ QVERIFY(!img.isNull());
+
+ capturedSignal.clear();
+ imageAvailableSignal.clear();
+ savedSignal.clear();
+
+ //Capture to yuv buffer
+#ifdef Q_WS_MAEMO_6
+ QVERIFY(imageCapture.supportedBufferFormats().contains(QVideoFrame::Format_UYVY));
+#endif
+
+ if (imageCapture.supportedBufferFormats().contains(QVideoFrame::Format_UYVY)) {
+ imageCapture.setBufferFormat(QVideoFrame::Format_UYVY);
+ QCOMPARE(imageCapture.bufferFormat(), QVideoFrame::Format_UYVY);
+
+ id = imageCapture.capture();
+ QTRY_VERIFY(!imageAvailableSignal.isEmpty());
+
+ QVERIFY(errorSignal.isEmpty());
+ QVERIFY(!capturedSignal.isEmpty());
+ QVERIFY(!imageAvailableSignal.isEmpty());
+ QVERIFY(savedSignal.isEmpty());
+
+ QTest::qWait(2000);
+ QVERIFY(savedSignal.isEmpty());
+
+ frame = imageAvailableSignal.first().last().value<QVideoFrame>();
+ QVERIFY(frame.isValid());
+
+ qDebug() << frame.pixelFormat();
+ QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_UYVY);
+ QVERIFY(!frame.size().isEmpty());
+ frame = QVideoFrame();
+
+ capturedSignal.clear();
+ imageAvailableSignal.clear();
+ savedSignal.clear();
+
+ imageCapture.setBufferFormat(QVideoFrame::Format_Jpeg);
+ QCOMPARE(imageCapture.bufferFormat(), QVideoFrame::Format_Jpeg);
+ }
+
+ //Try to capture to both buffer and file
+#ifdef Q_WS_MAEMO_6
+ QVERIFY(imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer | QCameraImageCapture::CaptureToFile));
+#endif
+ if (imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer | QCameraImageCapture::CaptureToFile)) {
+ imageCapture.setCaptureDestination(QCameraImageCapture::CaptureToBuffer | QCameraImageCapture::CaptureToFile);
+
+ int oldId = id;
+ id = imageCapture.capture();
+ QVERIFY(id != oldId);
+ QTRY_VERIFY(!savedSignal.isEmpty());
+
+ QVERIFY(errorSignal.isEmpty());
+ QVERIFY(!capturedSignal.isEmpty());
+ QVERIFY(!imageAvailableSignal.isEmpty());
+ QVERIFY(!savedSignal.isEmpty());
+
+ QCOMPARE(capturedSignal.first().first().toInt(), id);
+ QCOMPARE(imageAvailableSignal.first().first().toInt(), id);
+
+ frame = imageAvailableSignal.first().last().value<QVideoFrame>();
+ QVERIFY(frame.isValid());
+ QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_Jpeg);
+ QVERIFY(!frame.size().isEmpty());
+
+ QString fileName = savedSignal.first().last().toString();
+ QVERIFY(QFileInfo(fileName).exists());
+ }
+}
+
+void tst_QCameraBackend::testCameraCaptureMetadata()
+{
+#ifndef Q_WS_MAEMO_6
+ QSKIP("Capture metadata is supported only on harmattan", SkipAll);
+#endif
+
+ QCamera camera;
+ QCameraImageCapture imageCapture(&camera);
+ camera.exposure()->setFlashMode(QCameraExposure::FlashOff);
+
+ QSignalSpy metadataSignal(&imageCapture, SIGNAL(imageMetadataAvailable(int,QtMultimediaKit::MetaData,QVariant)));
+ QSignalSpy savedSignal(&imageCapture, SIGNAL(imageSaved(int,QString)));
+
+ camera.start();
+
+ QTRY_VERIFY(imageCapture.isReadyForCapture());
+
+ int id = imageCapture.capture(QString::fromLatin1("/dev/null"));
+ QTRY_VERIFY(!savedSignal.isEmpty());
+ QVERIFY(!metadataSignal.isEmpty());
+ QCOMPARE(metadataSignal.first().first().toInt(), id);
+}
+
+void tst_QCameraBackend::testExposureCompensation()
+{
+#if !defined(Q_WS_MAEMO_6) && !defined(Q_WS_MAEMO_5) && !defined(Q_OS_SYMBIAN)
+ QSKIP("Capture exposure parameters are supported only on mobile platforms", SkipAll);
+#endif
+
+ QCamera camera;
+ QCameraExposure *exposure = camera.exposure();
+
+ QSignalSpy exposureCompensationSignal(exposure, SIGNAL(exposureCompensationChanged(qreal)));
+
+#ifdef Q_OS_SYMBIAN
+ // Camera needs to be started, see: QTMOBILITY-1566
+ camera.load();
+ QTRY_COMPARE(camera.status(), QCamera::LoadedStatus);
+#endif // Q_OS_SYMBIAN
+
+ //it should be possible to set exposure parameters in Unloaded state
+ QCOMPARE(exposure->exposureCompensation()+1.0, 1.0);
+ exposure->setExposureCompensation(1.0);
+ QCOMPARE(exposure->exposureCompensation(), 1.0);
+ QTRY_COMPARE(exposureCompensationSignal.count(), 1);
+ QCOMPARE(exposureCompensationSignal.last().first().toReal(), 1.0);
+
+ //exposureCompensationChanged should not be emitted when value is not changed
+ exposure->setExposureCompensation(1.0);
+ QTest::qWait(50);
+ QCOMPARE(exposureCompensationSignal.count(), 1);
+
+ //exposure compensation should be preserved during load/start
+ camera.load();
+ QTRY_COMPARE(camera.status(), QCamera::LoadedStatus);
+
+ QCOMPARE(exposure->exposureCompensation(), 1.0);
+
+ exposureCompensationSignal.clear();
+ exposure->setExposureCompensation(-1.0);
+ QCOMPARE(exposure->exposureCompensation(), -1.0);
+ QTRY_COMPARE(exposureCompensationSignal.count(), 1);
+ QCOMPARE(exposureCompensationSignal.last().first().toReal(), -1.0);
+
+ camera.start();
+ QTRY_COMPARE(camera.status(), QCamera::ActiveStatus);
+
+ QCOMPARE(exposure->exposureCompensation(), -1.0);
+
+ exposureCompensationSignal.clear();
+ exposure->setExposureCompensation(1.0);
+ QCOMPARE(exposure->exposureCompensation(), 1.0);
+ QTRY_COMPARE(exposureCompensationSignal.count(), 1);
+ QCOMPARE(exposureCompensationSignal.last().first().toReal(), 1.0);
+}
+
+void tst_QCameraBackend::testExposureMode()
+{
+#if !defined(Q_WS_MAEMO_6) && !defined(Q_WS_MAEMO_5) && !defined(Q_OS_SYMBIAN)
+ QSKIP("Capture exposure parameters are supported only on mobile platforms", SkipAll);
+#endif
+
+ QCamera camera;
+ QCameraExposure *exposure = camera.exposure();
+
+#ifdef Q_WS_MAEMO_6
+ QEXPECT_FAIL("", "Camerabin reports Manual exposure instead of Auto", Continue);
+#endif
+ QCOMPARE(exposure->exposureMode(), QCameraExposure::ExposureAuto);
+
+#ifdef Q_OS_SYMBIAN
+ // Camera needs to be started, see: QTMOBILITY-1566
+ camera.load();
+ QTRY_COMPARE(camera.status(), QCamera::LoadedStatus);
+#endif // Q_OS_SYMBIAN
+
+ // Night
+ exposure->setExposureMode(QCameraExposure::ExposureNight);
+ QCOMPARE(exposure->exposureMode(), QCameraExposure::ExposureNight);
+ camera.start();
+ QTRY_COMPARE(camera.status(), QCamera::ActiveStatus);
+ QCOMPARE(exposure->exposureMode(), QCameraExposure::ExposureNight);
+
+ camera.unload();
+ QTRY_COMPARE(camera.status(), QCamera::UnloadedStatus);
+
+#ifdef Q_OS_SYMBIAN
+ // Camera needs to be started, see: QTMOBILITY-1566
+ camera.load();
+ QTRY_COMPARE(camera.status(), QCamera::LoadedStatus);
+#endif // Q_OS_SYMBIAN
+
+ // Auto
+ exposure->setExposureMode(QCameraExposure::ExposureAuto);
+ QCOMPARE(exposure->exposureMode(), QCameraExposure::ExposureAuto);
+ camera.start();
+ QTRY_COMPARE(camera.status(), QCamera::ActiveStatus);
+ QCOMPARE(exposure->exposureMode(), QCameraExposure::ExposureAuto);
+}
+
+QTEST_MAIN(tst_QCameraBackend)
+
+#include "tst_qcamerabackend.moc"
diff --git a/tests/auto/qdeclarativeaudio/qdeclarativeaudio.pro b/tests/auto/qdeclarativeaudio/qdeclarativeaudio.pro
new file mode 100644
index 000000000..a7ab28581
--- /dev/null
+++ b/tests/auto/qdeclarativeaudio/qdeclarativeaudio.pro
@@ -0,0 +1,18 @@
+load(qttest_p4)
+
+QT += multimediakit-private declarative
+
+# TARGET = tst_qdeclarativeaudio
+# CONFIG += testcase
+
+HEADERS += \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativeaudio_p.h \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativemediabase_p.h \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativemediametadata_p.h
+
+SOURCES += \
+ tst_qdeclarativeaudio.cpp \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativeaudio.cpp \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativemediabase.cpp
+
+INCLUDEPATH += $$QT.multimediakit.sources/../imports/multimedia
diff --git a/tests/auto/qdeclarativeaudio/tst_qdeclarativeaudio.cpp b/tests/auto/qdeclarativeaudio/tst_qdeclarativeaudio.cpp
new file mode 100644
index 000000000..df7025f6f
--- /dev/null
+++ b/tests/auto/qdeclarativeaudio/tst_qdeclarativeaudio.cpp
@@ -0,0 +1,1302 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=plugins/declarative/multimedia
+
+#include <QtTest/QtTest>
+
+#include "qdeclarativeaudio_p.h"
+#include "qdeclarativemediametadata_p.h"
+
+#include <qmediaplayercontrol.h>
+#include <qmediaservice.h>
+#include <qmediaserviceprovider.h>
+#include <qmetadatareadercontrol.h>
+
+#include <QtGui/qapplication.h>
+
+class tst_QDeclarativeAudio : public QObject
+{
+ Q_OBJECT
+public slots:
+ void initTestCase();
+
+private slots:
+ void nullPlayerControl();
+ void nullMetaDataControl();
+ void nullService();
+
+ void source();
+ void autoLoad();
+ void playing();
+ void paused();
+ void duration();
+ void position();
+ void volume();
+ void muted();
+ void bufferProgress();
+ void seekable();
+ void playbackRate();
+ void status();
+ void metaData_data();
+ void metaData();
+ void error();
+ void loops();
+};
+
+Q_DECLARE_METATYPE(QtMultimediaKit::MetaData);
+Q_DECLARE_METATYPE(QDeclarativeAudio::Error);
+
+class QtTestMediaPlayerControl : public QMediaPlayerControl
+{
+ Q_OBJECT
+public:
+ QtTestMediaPlayerControl(QObject *parent = 0)
+ : QMediaPlayerControl(parent)
+ , m_state(QMediaPlayer::StoppedState)
+ , m_mediaStatus(QMediaPlayer::NoMedia)
+ , m_duration(0)
+ , m_position(0)
+ , m_playbackRate(1.0)
+ , m_volume(50)
+ , m_bufferStatus(0)
+ , m_muted(false)
+ , m_audioAvailable(false)
+ , m_videoAvailable(false)
+ , m_seekable(false)
+ {
+ }
+
+ QMediaPlayer::State state() const { return m_state; }
+ void updateState(QMediaPlayer::State state) { emit stateChanged(m_state = state); }
+
+ QMediaPlayer::MediaStatus mediaStatus() const { return m_mediaStatus; }
+ void updateMediaStatus(QMediaPlayer::MediaStatus status) {
+ emit mediaStatusChanged(m_mediaStatus = status); }
+ void updateMediaStatus(QMediaPlayer::MediaStatus status, QMediaPlayer::State state)
+ {
+ m_mediaStatus = status;
+ m_state = state;
+
+ emit mediaStatusChanged(m_mediaStatus);
+ emit stateChanged(m_state);
+ }
+
+ qint64 duration() const { return m_duration; }
+ void setDuration(qint64 duration) { emit durationChanged(m_duration = duration); }
+
+ qint64 position() const { return m_position; }
+ void setPosition(qint64 position) { emit positionChanged(m_position = position); }
+
+ int volume() const { return m_volume; }
+ void setVolume(int volume) { emit volumeChanged(m_volume = volume); }
+
+ bool isMuted() const { return m_muted; }
+ void setMuted(bool muted) { emit mutedChanged(m_muted = muted); }
+
+ int bufferStatus() const { return m_bufferStatus; }
+ void setBufferStatus(int status) { emit bufferStatusChanged(m_bufferStatus = status); }
+
+ bool isAudioAvailable() const { return m_audioAvailable; }
+ void setAudioAvailable(bool available) {
+ emit audioAvailableChanged(m_audioAvailable = available); }
+ bool isVideoAvailable() const { return m_videoAvailable; }
+ void setVideoAvailable(bool available) {
+ emit videoAvailableChanged(m_videoAvailable = available); }
+
+ bool isSeekable() const { return m_seekable; }
+ void setSeekable(bool seekable) { emit seekableChanged(m_seekable = seekable); }
+
+ QMediaTimeRange availablePlaybackRanges() const { return QMediaTimeRange(); }
+
+ qreal playbackRate() const { return m_playbackRate; }
+ void setPlaybackRate(qreal rate) { emit playbackRateChanged(m_playbackRate = rate); }
+
+ QMediaContent media() const { return m_media; }
+ const QIODevice *mediaStream() const { return 0; }
+ void setMedia(const QMediaContent &media, QIODevice *)
+ {
+ m_media = media;
+
+ m_mediaStatus = m_media.isNull()
+ ? QMediaPlayer::NoMedia
+ : QMediaPlayer::LoadingMedia;
+
+ emit mediaChanged(m_media);
+ emit mediaStatusChanged(m_mediaStatus);
+ }
+
+ void play()
+ {
+ m_state = QMediaPlayer::PlayingState;
+ if (m_mediaStatus == QMediaPlayer::EndOfMedia)
+ updateMediaStatus(QMediaPlayer::LoadedMedia);
+ emit stateChanged(m_state);
+ }
+ void pause() { emit stateChanged(m_state = QMediaPlayer::PausedState); }
+ void stop() { emit stateChanged(m_state = QMediaPlayer::StoppedState); }
+
+ void emitError(QMediaPlayer::Error err, const QString &errorString) {
+ emit error(err, errorString); }
+
+private:
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_mediaStatus;
+ qint64 m_duration;
+ qint64 m_position;
+ qreal m_playbackRate;
+ int m_volume;
+ int m_bufferStatus;
+ bool m_muted;
+ bool m_audioAvailable;
+ bool m_videoAvailable;
+ bool m_seekable;
+ QMediaContent m_media;
+};
+
+class QtTestMetaDataControl : public QMetaDataReaderControl
+{
+ Q_OBJECT
+public:
+ QtTestMetaDataControl(QObject *parent = 0)
+ : QMetaDataReaderControl(parent)
+ {
+ }
+
+ bool isMetaDataAvailable() const { return true; }
+
+ QVariant metaData(QtMultimediaKit::MetaData key) const { return m_metaData.value(key); }
+ void setMetaData(QtMultimediaKit::MetaData key, const QVariant &value) {
+ m_metaData.insert(key, value); emit metaDataChanged(); }
+
+ QList<QtMultimediaKit::MetaData> availableMetaData() const { return m_metaData.keys(); }
+
+ QVariant extendedMetaData(const QString &) const { return QVariant(); }
+ QStringList availableExtendedMetaData() const { return QStringList(); }
+
+private:
+ QMap<QtMultimediaKit::MetaData, QVariant> m_metaData;
+};
+
+class QtTestMediaService : public QMediaService
+{
+ Q_OBJECT
+public:
+ QtTestMediaService(
+ QtTestMediaPlayerControl *playerControl,
+ QtTestMetaDataControl *metaDataControl,
+ QObject *parent)
+ : QMediaService(parent)
+ , playerControl(playerControl)
+ , metaDataControl(metaDataControl)
+ {
+ }
+
+ QMediaControl *requestControl(const char *name)
+ {
+ if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
+ return playerControl;
+ else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
+ return metaDataControl;
+ else
+ return 0;
+ }
+
+ void releaseControl(QMediaControl *) {}
+
+ QtTestMediaPlayerControl *playerControl;
+ QtTestMetaDataControl *metaDataControl;
+};
+
+class QtTestMediaServiceProvider : public QMediaServiceProvider
+{
+ Q_OBJECT
+public:
+ QtTestMediaServiceProvider()
+ : service(new QtTestMediaService(
+ new QtTestMediaPlayerControl(this), new QtTestMetaDataControl(this), this))
+ {
+ setDefaultServiceProvider(this);
+ }
+
+ QtTestMediaServiceProvider(QtTestMediaService *service)
+ : service(service)
+ {
+ setDefaultServiceProvider(this);
+ }
+
+ QtTestMediaServiceProvider(
+ QtTestMediaPlayerControl *playerControl, QtTestMetaDataControl *metaDataControl)
+ : service(new QtTestMediaService(playerControl, metaDataControl, this))
+ {
+ setDefaultServiceProvider(this);
+ }
+
+ ~QtTestMediaServiceProvider()
+ {
+ setDefaultServiceProvider(0);
+ }
+
+ QMediaService *requestService(
+ const QByteArray &type,
+ const QMediaServiceProviderHint & = QMediaServiceProviderHint())
+ {
+ requestedService = type;
+
+ return service;
+ }
+
+ void releaseService(QMediaService *) {}
+
+ inline QtTestMediaPlayerControl *playerControl() { return service->playerControl; }
+ inline QtTestMetaDataControl *metaDataControl() { return service->metaDataControl; }
+
+ QtTestMediaService *service;
+ QByteArray requestedService;
+};
+
+void tst_QDeclarativeAudio::initTestCase()
+{
+ qRegisterMetaType<QDeclarativeAudio::Error>();
+}
+
+void tst_QDeclarativeAudio::nullPlayerControl()
+{
+ QtTestMetaDataControl metaDataControl;
+ QtTestMediaServiceProvider provider(0, &metaDataControl);
+
+ QDeclarativeAudio audio;
+ audio.classBegin();
+
+ QCOMPARE(audio.source(), QUrl());
+ audio.setSource(QUrl("http://example.com"));
+ QCOMPARE(audio.source(), QUrl("http://example.com"));
+
+ QCOMPARE(audio.isPlaying(), false);
+ audio.setPlaying(true);
+ QCOMPARE(audio.isPlaying(), true);
+ audio.setPlaying(false);
+ audio.play();
+ QCOMPARE(audio.isPlaying(), false);
+
+ QCOMPARE(audio.isPaused(), false);
+ audio.pause();
+ QCOMPARE(audio.isPaused(), false);
+ audio.setPaused(true);
+ QCOMPARE(audio.isPaused(), true);
+
+ QCOMPARE(audio.duration(), 0);
+
+ QCOMPARE(audio.position(), 0);
+ audio.setPosition(10000);
+ QCOMPARE(audio.position(), 10000);
+
+ QCOMPARE(audio.volume(), qreal(1.0));
+ audio.setVolume(0.5);
+ QCOMPARE(audio.volume(), qreal(0.5));
+
+ QCOMPARE(audio.isMuted(), false);
+ audio.setMuted(true);
+ QCOMPARE(audio.isMuted(), true);
+
+ QCOMPARE(audio.bufferProgress(), qreal(0));
+
+ QCOMPARE(audio.isSeekable(), false);
+
+ QCOMPARE(audio.playbackRate(), qreal(1.0));
+
+ QCOMPARE(audio.status(), QDeclarativeAudio::NoMedia);
+
+ QCOMPARE(audio.error(), QDeclarativeAudio::ServiceMissing);
+}
+
+void tst_QDeclarativeAudio::nullMetaDataControl()
+{
+ QtTestMediaPlayerControl playerControl;
+ QtTestMediaServiceProvider provider(&playerControl, 0);
+
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QVERIFY(audio.metaData());
+}
+
+void tst_QDeclarativeAudio::nullService()
+{
+ QtTestMediaServiceProvider provider(0);
+
+ QDeclarativeAudio audio;
+ audio.classBegin();
+
+ QCOMPARE(audio.source(), QUrl());
+ audio.setSource(QUrl("http://example.com"));
+ QCOMPARE(audio.source(), QUrl("http://example.com"));
+
+ QCOMPARE(audio.isPlaying(), false);
+ audio.setPlaying(true);
+ QCOMPARE(audio.isPlaying(), true);
+ audio.setPlaying(false);
+ audio.play();
+ QCOMPARE(audio.isPlaying(), false);
+
+ QCOMPARE(audio.isPaused(), false);
+ audio.pause();
+ QCOMPARE(audio.isPaused(), false);
+ audio.setPaused(true);
+ QCOMPARE(audio.isPaused(), true);
+
+ QCOMPARE(audio.duration(), 0);
+
+ QCOMPARE(audio.position(), 0);
+ audio.setPosition(10000);
+ QCOMPARE(audio.position(), 10000);
+
+ QCOMPARE(audio.volume(), qreal(1.0));
+ audio.setVolume(0.5);
+ QCOMPARE(audio.volume(), qreal(0.5));
+
+ QCOMPARE(audio.isMuted(), false);
+ audio.setMuted(true);
+ QCOMPARE(audio.isMuted(), true);
+
+ QCOMPARE(audio.bufferProgress(), qreal(0));
+
+ QCOMPARE(audio.isSeekable(), false);
+
+ QCOMPARE(audio.playbackRate(), qreal(1.0));
+
+ QCOMPARE(audio.status(), QDeclarativeAudio::NoMedia);
+
+ QCOMPARE(audio.error(), QDeclarativeAudio::ServiceMissing);
+
+ QVERIFY(audio.metaData());
+}
+
+void tst_QDeclarativeAudio::source()
+{
+ const QUrl url1("http://example.com");
+ const QUrl url2("file:///local/path");
+ const QUrl url3;
+
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(&audio, SIGNAL(sourceChanged()));
+
+ audio.setSource(url1);
+ QCOMPARE(audio.source(), url1);
+ QCOMPARE(provider.playerControl()->media().canonicalUrl(), url1);
+ QCOMPARE(spy.count(), 1);
+
+ audio.setSource(url2);
+ QCOMPARE(audio.source(), url2);
+ QCOMPARE(provider.playerControl()->media().canonicalUrl(), url2);
+ QCOMPARE(spy.count(), 2);
+
+ audio.setSource(url3);
+ QCOMPARE(audio.source(), url3);
+ QCOMPARE(provider.playerControl()->media().canonicalUrl(), url3);
+ QCOMPARE(spy.count(), 3);
+}
+
+void tst_QDeclarativeAudio::autoLoad()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(&audio, SIGNAL(autoLoadChanged()));
+
+ QCOMPARE(audio.isAutoLoad(), true);
+
+ audio.setAutoLoad(false);
+ QCOMPARE(audio.isAutoLoad(), false);
+ QCOMPARE(spy.count(), 1);
+
+ audio.setSource(QUrl("http://example.com"));
+ QCOMPARE(audio.source(), QUrl("http://example.com"));
+ audio.play();
+ QCOMPARE(audio.isPlaying(), true);
+ audio.stop();
+
+ audio.setAutoLoad(true);
+ audio.setSource(QUrl("http://example.com"));
+ audio.setPaused(true);
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(audio.isPaused(), true);
+}
+
+void tst_QDeclarativeAudio::playing()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+
+ QSignalSpy playingChangedSpy(&audio, SIGNAL(playingChanged()));
+ QSignalSpy startedSpy(&audio, SIGNAL(started()));
+ QSignalSpy stoppedSpy(&audio, SIGNAL(stopped()));
+
+ int playingChanged = 0;
+ int started = 0;
+ int stopped = 0;
+
+ audio.componentComplete();
+ audio.setSource(QUrl("http://example.com"));
+
+ QCOMPARE(audio.isPlaying(), false);
+
+ // setPlaying(true) when stopped.
+ audio.setPlaying(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when playing.
+ audio.setPlaying(false);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // play() when stopped.
+ audio.play();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // stop() when playing.
+ audio.stop();
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // stop() when stopped.
+ audio.stop();
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when stopped.
+ audio.setPlaying(false);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ audio.setPlaying(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(true) when playing.
+ audio.setPlaying(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // play() when playing.
+ audio.play();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+}
+
+void tst_QDeclarativeAudio::paused()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+
+ QSignalSpy playingChangedSpy(&audio, SIGNAL(playingChanged()));
+ QSignalSpy pausedChangedSpy(&audio, SIGNAL(pausedChanged()));
+ QSignalSpy startedSpy(&audio, SIGNAL(started()));
+ QSignalSpy pausedSpy(&audio, SIGNAL(paused()));
+ QSignalSpy resumedSpy(&audio, SIGNAL(resumed()));
+ QSignalSpy stoppedSpy(&audio, SIGNAL(stopped()));
+
+ int playingChanged = 0;
+ int pausedChanged = 0;
+ int started = 0;
+ int paused = 0;
+ int resumed = 0;
+ int stopped = 0;
+
+ audio.componentComplete();
+ audio.setSource(QUrl("http://example.com"));
+
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), false);
+
+ // setPlaying(true) when stopped.
+ audio.setPlaying(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(true) when playing.
+ audio.setPaused(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(true) when paused.
+ audio.setPaused(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // pause() when paused.
+ audio.pause();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(false) when paused.
+ audio.setPaused(false);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), ++resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(false) when playing.
+ audio.setPaused(false);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // pause() when playing.
+ audio.pause();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when paused.
+ audio.setPlaying(false);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // setPaused(true) when stopped and paused.
+ audio.setPaused(true);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(false) when stopped and paused.
+ audio.setPaused(false);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(true) when stopped.
+ audio.setPaused(true);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(true) when stopped and paused.
+ audio.setPlaying(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // play() when paused.
+ audio.play();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), ++resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(true) when playing.
+ audio.setPaused(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // stop() when paused.
+ audio.stop();
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // setPaused(true) when stopped.
+ audio.setPaused(true);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // stop() when stopped and paused.
+ audio.stop();
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // pause() when stopped.
+ audio.pause();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when paused.
+ audio.setPlaying(false);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // pause() when stopped and paused.
+ audio.pause();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when paused.
+ audio.setPlaying(false);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(audio.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // play() when stopped and paused.
+ audio.play();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(audio.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+}
+
+void tst_QDeclarativeAudio::duration()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(&audio, SIGNAL(durationChanged()));
+
+ QCOMPARE(audio.duration(), 0);
+
+ provider.playerControl()->setDuration(4040);
+ QCOMPARE(audio.duration(), 4040);
+ QCOMPARE(spy.count(), 1);
+
+ provider.playerControl()->setDuration(-129);
+ QCOMPARE(audio.duration(), -129);
+ QCOMPARE(spy.count(), 2);
+
+ provider.playerControl()->setDuration(0);
+ QCOMPARE(audio.duration(), 0);
+ QCOMPARE(spy.count(), 3);
+
+ // Unnecessary duration changed signals aren't filtered.
+ provider.playerControl()->setDuration(0);
+ QCOMPARE(audio.duration(), 0);
+ QCOMPARE(spy.count(), 4);
+}
+
+void tst_QDeclarativeAudio::position()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(&audio, SIGNAL(positionChanged()));
+
+ QCOMPARE(audio.position(), 0);
+
+ // QDeclarativeAudio won't bound set positions to the duration. A media service may though.
+ QCOMPARE(audio.duration(), 0);
+
+ audio.setPosition(450);
+ QCOMPARE(audio.position(), 450);
+ QCOMPARE(provider.playerControl()->position(), qint64(450));
+ QCOMPARE(spy.count(), 1);
+
+ audio.setPosition(-5403);
+ QCOMPARE(audio.position(), -5403);
+ QCOMPARE(provider.playerControl()->position(), qint64(-5403));
+ QCOMPARE(spy.count(), 2);
+
+ audio.setPosition(-5403);
+ QCOMPARE(audio.position(), -5403);
+ QCOMPARE(provider.playerControl()->position(), qint64(-5403));
+ QCOMPARE(spy.count(), 2);
+
+ // Check the signal change signal is emitted if the change originates from the media service.
+ provider.playerControl()->setPosition(0);
+ QCOMPARE(audio.position(), 0);
+ QCOMPARE(spy.count(), 3);
+
+ connect(&audio, SIGNAL(positionChanged()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ provider.playerControl()->updateState(QMediaPlayer::PlayingState);
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(spy.count() > 3 && spy.count() < 6); // 4 or 5
+
+ provider.playerControl()->updateState(QMediaPlayer::PausedState);
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(spy.count() < 6);
+}
+
+void tst_QDeclarativeAudio::volume()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(&audio, SIGNAL(volumeChanged()));
+
+ QCOMPARE(audio.volume(), qreal(1.0));
+
+ audio.setVolume(0.7);
+ QCOMPARE(audio.volume(), qreal(0.7));
+ QCOMPARE(provider.playerControl()->volume(), 70);
+ QCOMPARE(spy.count(), 1);
+
+ audio.setVolume(0.7);
+ QCOMPARE(audio.volume(), qreal(0.7));
+ QCOMPARE(provider.playerControl()->volume(), 70);
+ QCOMPARE(spy.count(), 1);
+
+ provider.playerControl()->setVolume(30);
+ QCOMPARE(audio.volume(), qreal(0.3));
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_QDeclarativeAudio::muted()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(&audio, SIGNAL(mutedChanged()));
+
+ QCOMPARE(audio.isMuted(), false);
+
+ audio.setMuted(true);
+ QCOMPARE(audio.isMuted(), true);
+ QCOMPARE(provider.playerControl()->isMuted(), true);
+ QCOMPARE(spy.count(), 1);
+
+ provider.playerControl()->setMuted(false);
+ QCOMPARE(audio.isMuted(), false);
+ QCOMPARE(spy.count(), 2);
+
+ audio.setMuted(false);
+ QCOMPARE(audio.isMuted(), false);
+ QCOMPARE(provider.playerControl()->isMuted(), false);
+ QCOMPARE(spy.count(), 3);
+}
+
+void tst_QDeclarativeAudio::bufferProgress()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(&audio, SIGNAL(bufferProgressChanged()));
+
+ QCOMPARE(audio.bufferProgress(), qreal(0.0));
+
+ provider.playerControl()->setBufferStatus(20);
+ QCOMPARE(audio.bufferProgress(), qreal(0.2));
+ QCOMPARE(spy.count(), 1);
+
+ provider.playerControl()->setBufferStatus(20);
+ QCOMPARE(audio.bufferProgress(), qreal(0.2));
+ QCOMPARE(spy.count(), 2);
+
+ provider.playerControl()->setBufferStatus(40);
+ QCOMPARE(audio.bufferProgress(), qreal(0.4));
+ QCOMPARE(spy.count(), 3);
+
+ connect(&audio, SIGNAL(positionChanged()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ provider.playerControl()->updateMediaStatus(
+ QMediaPlayer::BufferingMedia, QMediaPlayer::PlayingState);
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(spy.count() > 3 && spy.count() < 6); // 4 or 5
+
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferedMedia);
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(spy.count() < 6);
+}
+
+void tst_QDeclarativeAudio::seekable()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(&audio, SIGNAL(seekableChanged()));
+
+ QCOMPARE(audio.isSeekable(), false);
+
+ provider.playerControl()->setSeekable(true);
+ QCOMPARE(audio.isSeekable(), true);
+ QCOMPARE(spy.count(), 1);
+
+ provider.playerControl()->setSeekable(true);
+ QCOMPARE(audio.isSeekable(), true);
+ QCOMPARE(spy.count(), 2);
+
+ provider.playerControl()->setSeekable(false);
+ QCOMPARE(audio.isSeekable(), false);
+ QCOMPARE(spy.count(), 3);
+}
+
+void tst_QDeclarativeAudio::playbackRate()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(&audio, SIGNAL(playbackRateChanged()));
+
+ QCOMPARE(audio.playbackRate(), qreal(1.0));
+
+ audio.setPlaybackRate(0.5);
+ QCOMPARE(audio.playbackRate(), qreal(0.5));
+ QCOMPARE(provider.playerControl()->playbackRate(), qreal(0.5));
+ QCOMPARE(spy.count(), 1);
+
+ provider.playerControl()->setPlaybackRate(2.0);
+ QCOMPARE(provider.playerControl()->playbackRate(), qreal(2.0));
+ QCOMPARE(spy.count(), 2);
+
+ audio.setPlaybackRate(2.0);
+ QCOMPARE(audio.playbackRate(), qreal(2.0));
+ QCOMPARE(provider.playerControl()->playbackRate(), qreal(2.0));
+ QCOMPARE(spy.count(), 3);
+}
+
+void tst_QDeclarativeAudio::status()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy statusChangedSpy(&audio, SIGNAL(statusChanged()));
+
+ QCOMPARE(audio.status(), QDeclarativeAudio::NoMedia);
+
+ // Set media, start loading.
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::LoadingMedia);
+ QCOMPARE(audio.status(), QDeclarativeAudio::Loading);
+ QCOMPARE(statusChangedSpy.count(), 1);
+
+ // Finish loading.
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::LoadedMedia);
+ QCOMPARE(audio.status(), QDeclarativeAudio::Loaded);
+ QCOMPARE(statusChangedSpy.count(), 2);
+
+ // Play, start buffering.
+ provider.playerControl()->updateMediaStatus(
+ QMediaPlayer::StalledMedia, QMediaPlayer::PlayingState);
+ QCOMPARE(audio.status(), QDeclarativeAudio::Stalled);
+ QCOMPARE(statusChangedSpy.count(), 3);
+
+ // Enough data buffered to proceed.
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferingMedia);
+ QCOMPARE(audio.status(), QDeclarativeAudio::Buffering);
+ QCOMPARE(statusChangedSpy.count(), 4);
+
+ // Errant second buffering status changed.
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferingMedia);
+ QCOMPARE(audio.status(), QDeclarativeAudio::Buffering);
+ QCOMPARE(statusChangedSpy.count(), 4);
+
+ // Buffer full.
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferedMedia);
+ QCOMPARE(audio.status(), QDeclarativeAudio::Buffered);
+ QCOMPARE(statusChangedSpy.count(), 5);
+
+ // Buffer getting low.
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferingMedia);
+ QCOMPARE(audio.status(), QDeclarativeAudio::Buffering);
+ QCOMPARE(statusChangedSpy.count(), 6);
+
+ // Buffer full.
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferedMedia);
+ QCOMPARE(audio.status(), QDeclarativeAudio::Buffered);
+ QCOMPARE(statusChangedSpy.count(), 7);
+
+ // Finished.
+ provider.playerControl()->updateMediaStatus(
+ QMediaPlayer::EndOfMedia, QMediaPlayer::StoppedState);
+ QCOMPARE(audio.status(), QDeclarativeAudio::EndOfMedia);
+ QCOMPARE(statusChangedSpy.count(), 8);
+}
+
+void tst_QDeclarativeAudio::metaData_data()
+{
+ QTest::addColumn<QByteArray>("propertyName");
+ QTest::addColumn<QtMultimediaKit::MetaData>("propertyKey");
+ QTest::addColumn<QVariant>("value");
+
+ QTest::newRow("title")
+ << QByteArray("title")
+ << QtMultimediaKit::Title
+ << QVariant(QString::fromLatin1("This is a title"));
+
+ QTest::newRow("genre")
+ << QByteArray("genre")
+ << QtMultimediaKit::Genre
+ << QVariant(QString::fromLatin1("rock"));
+
+ QTest::newRow("trackNumber")
+ << QByteArray("trackNumber")
+ << QtMultimediaKit::TrackNumber
+ << QVariant(8);
+}
+
+void tst_QDeclarativeAudio::metaData()
+{
+ QFETCH(QByteArray, propertyName);
+ QFETCH(QtMultimediaKit::MetaData, propertyKey);
+ QFETCH(QVariant, value);
+
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy spy(audio.metaData(), SIGNAL(metaDataChanged()));
+
+ const int index = audio.metaData()->metaObject()->indexOfProperty(propertyName.constData());
+ QVERIFY(index != -1);
+
+ QMetaProperty property = audio.metaData()->metaObject()->property(index);
+ QCOMPARE(property.read(&audio), QVariant());
+
+ property.write(audio.metaData(), value);
+ QCOMPARE(property.read(audio.metaData()), QVariant());
+ QCOMPARE(provider.metaDataControl()->metaData(propertyKey), QVariant());
+ QCOMPARE(spy.count(), 0);
+
+ provider.metaDataControl()->setMetaData(propertyKey, value);
+ QCOMPARE(property.read(audio.metaData()), value);
+ QCOMPARE(spy.count(), 1);
+}
+
+void tst_QDeclarativeAudio::error()
+{
+ const QString errorString = QLatin1String("Failed to open device.");
+
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+ audio.classBegin();
+ audio.componentComplete();
+
+ QSignalSpy errorSpy(&audio, SIGNAL(error(QDeclarativeAudio::Error,QString)));
+ QSignalSpy errorChangedSpy(&audio, SIGNAL(errorChanged()));
+
+ QCOMPARE(audio.error(), QDeclarativeAudio::NoError);
+ QCOMPARE(audio.errorString(), QString());
+
+ provider.playerControl()->emitError(QMediaPlayer::ResourceError, errorString);
+
+ QCOMPARE(audio.error(), QDeclarativeAudio::ResourceError);
+ QCOMPARE(audio.errorString(), errorString);
+ QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorChangedSpy.count(), 1);
+
+ // Changing the source resets the error properties.
+ audio.setSource(QUrl("http://example.com"));
+ QCOMPARE(audio.error(), QDeclarativeAudio::NoError);
+ QCOMPARE(audio.errorString(), QString());
+ QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorChangedSpy.count(), 2);
+
+ // But isn't noisy.
+ audio.setSource(QUrl("file:///file/path"));
+ QCOMPARE(audio.error(), QDeclarativeAudio::NoError);
+ QCOMPARE(audio.errorString(), QString());
+ QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorChangedSpy.count(), 2);
+}
+
+void tst_QDeclarativeAudio::loops()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeAudio audio;
+
+ QSignalSpy loopsChangedSpy(&audio, SIGNAL(loopCountChanged()));
+ QSignalSpy playingChangedSpy(&audio, SIGNAL(playingChanged()));
+ QSignalSpy stoppedSpy(&audio, SIGNAL(stopped()));
+
+ int playingChanged = 0;
+ int stopped = 0;
+ int loopsChanged = 0;
+
+ audio.classBegin();
+ audio.componentComplete();
+
+ QCOMPARE(audio.isPlaying(), false);
+
+ //setLoopCount(3) when stopped.
+ audio.setLoopCount(3);
+ QCOMPARE(audio.loopCount(), 3);
+ QCOMPARE(loopsChangedSpy.count(), ++loopsChanged);
+
+ //play till end
+ audio.play();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+
+ // setPlaying(true) when playing.
+ audio.setPlaying(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::EndOfMedia, QMediaPlayer::StoppedState);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+
+ //play to end
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::EndOfMedia, QMediaPlayer::StoppedState);
+ //play to end
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::EndOfMedia, QMediaPlayer::StoppedState);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // stop when playing
+ audio.play();
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::EndOfMedia, QMediaPlayer::StoppedState);
+ audio.stop();
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ //setPlaying(true) with infinite loop
+ audio.setLoopCount(-1);
+ QCOMPARE(audio.loopCount(), -1);
+ QCOMPARE(loopsChangedSpy.count(), ++loopsChanged);
+ audio.setPlaying(true);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ provider.playerControl()->updateMediaStatus(QMediaPlayer::EndOfMedia, QMediaPlayer::StoppedState);
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+
+ // play() when playing.
+ audio.play();
+ QCOMPARE(audio.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when playing in infinite loop.
+ audio.setPlaying(false);
+ QCOMPARE(audio.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+}
+
+QTEST_MAIN(tst_QDeclarativeAudio)
+
+#include "tst_qdeclarativeaudio.moc"
diff --git a/tests/auto/qdeclarativevideo/qdeclarativevideo.pro b/tests/auto/qdeclarativevideo/qdeclarativevideo.pro
new file mode 100644
index 000000000..15e58d8a5
--- /dev/null
+++ b/tests/auto/qdeclarativevideo/qdeclarativevideo.pro
@@ -0,0 +1,18 @@
+load(qttest_p4)
+
+QT += multimediakit-private declarative
+
+# TARGET = tst_qdeclarativevideo
+# CONFIG += testcase
+
+HEADERS += \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativevideo_p.h \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativemediabase_p.h \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativemediametadata_p.h
+
+SOURCES += \
+ tst_qdeclarativevideo.cpp \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativevideo.cpp \
+ $$QT.multimediakit.sources/../imports/multimedia/qdeclarativemediabase.cpp
+
+INCLUDEPATH += $$QT.multimediakit.sources/../imports/multimedia
diff --git a/tests/auto/qdeclarativevideo/tst_qdeclarativevideo.cpp b/tests/auto/qdeclarativevideo/tst_qdeclarativevideo.cpp
new file mode 100644
index 000000000..1f48a5c11
--- /dev/null
+++ b/tests/auto/qdeclarativevideo/tst_qdeclarativevideo.cpp
@@ -0,0 +1,992 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=plugins/declarative/multimedia
+
+#include <QtTest/QtTest>
+
+#include "qdeclarativevideo_p.h"
+
+
+#include <qabstractvideosurface.h>
+#include <qgraphicsvideoitem.h>
+#include <qmediaplayercontrol.h>
+#include <qmediaservice.h>
+#include <qmediaserviceprovider.h>
+#include <qvideorenderercontrol.h>
+#include <qvideowindowcontrol.h>
+#include <qvideosurfaceformat.h>
+
+#include <QtGui/qapplication.h>
+#include <QtGui/qpainter.h>
+
+class tst_QDeclarativeVideo : public QObject
+{
+ Q_OBJECT
+public slots:
+ void initTestCase();
+
+private slots:
+ void nullPlayerControl();
+ void nullService();
+
+ void playing();
+ void paused();
+ void error();
+
+ void hasAudio();
+ void hasVideo();
+ void fillMode();
+ void geometry();
+};
+
+Q_DECLARE_METATYPE(QtMultimediaKit::MetaData);
+Q_DECLARE_METATYPE(QDeclarativeVideo::Error);
+
+class QtTestMediaPlayerControl : public QMediaPlayerControl
+{
+ Q_OBJECT
+public:
+ QtTestMediaPlayerControl(QObject *parent = 0)
+ : QMediaPlayerControl(parent)
+ , m_state(QMediaPlayer::StoppedState)
+ , m_mediaStatus(QMediaPlayer::NoMedia)
+ , m_duration(0)
+ , m_position(0)
+ , m_playbackRate(1.0)
+ , m_volume(50)
+ , m_bufferStatus(0)
+ , m_muted(false)
+ , m_audioAvailable(false)
+ , m_videoAvailable(false)
+ , m_seekable(false)
+ {
+ }
+
+ QMediaPlayer::State state() const { return m_state; }
+ void updateState(QMediaPlayer::State state) { emit stateChanged(m_state = state); }
+
+ QMediaPlayer::MediaStatus mediaStatus() const { return m_mediaStatus; }
+ void updateMediaStatus(QMediaPlayer::MediaStatus status) {
+ emit mediaStatusChanged(m_mediaStatus = status); }
+ void updateMediaStatus(QMediaPlayer::MediaStatus status, QMediaPlayer::State state)
+ {
+ m_mediaStatus = status;
+ m_state = state;
+
+ emit mediaStatusChanged(m_mediaStatus);
+ emit stateChanged(m_state);
+ }
+
+ qint64 duration() const { return m_duration; }
+ void setDuration(qint64 duration) { emit durationChanged(m_duration = duration); }
+
+ qint64 position() const { return m_position; }
+ void setPosition(qint64 position) { emit positionChanged(m_position = position); }
+
+ int volume() const { return m_volume; }
+ void setVolume(int volume) { emit volumeChanged(m_volume = volume); }
+
+ bool isMuted() const { return m_muted; }
+ void setMuted(bool muted) { emit mutedChanged(m_muted = muted); }
+
+ int bufferStatus() const { return m_bufferStatus; }
+ void setBufferStatus(int status) { emit bufferStatusChanged(m_bufferStatus = status); }
+
+ bool isAudioAvailable() const { return m_audioAvailable; }
+ void setAudioAvailable(bool available) {
+ emit audioAvailableChanged(m_audioAvailable = available); }
+ bool isVideoAvailable() const { return m_videoAvailable; }
+ void setVideoAvailable(bool available) {
+ emit videoAvailableChanged(m_videoAvailable = available); }
+
+ bool isSeekable() const { return m_seekable; }
+ void setSeekable(bool seekable) { emit seekableChanged(m_seekable = seekable); }
+
+ QMediaTimeRange availablePlaybackRanges() const { return QMediaTimeRange(); }
+
+ qreal playbackRate() const { return m_playbackRate; }
+ void setPlaybackRate(qreal rate) { emit playbackRateChanged(m_playbackRate = rate); }
+
+ QMediaContent media() const { return m_media; }
+ const QIODevice *mediaStream() const { return 0; }
+ void setMedia(const QMediaContent &media, QIODevice *)
+ {
+ m_media = media;
+
+ m_mediaStatus = m_media.isNull()
+ ? QMediaPlayer::NoMedia
+ : QMediaPlayer::LoadingMedia;
+
+ emit mediaChanged(m_media);
+ emit mediaStatusChanged(m_mediaStatus);
+ }
+
+ void play() { emit stateChanged(m_state = QMediaPlayer::PlayingState); }
+ void pause() { emit stateChanged(m_state = QMediaPlayer::PausedState); }
+ void stop() { emit stateChanged(m_state = QMediaPlayer::StoppedState); }
+
+ void emitError(QMediaPlayer::Error err, const QString &errorString) {
+ emit error(err, errorString); }
+
+private:
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_mediaStatus;
+ qint64 m_duration;
+ qint64 m_position;
+ qreal m_playbackRate;
+ int m_volume;
+ int m_bufferStatus;
+ bool m_muted;
+ bool m_audioAvailable;
+ bool m_videoAvailable;
+ bool m_seekable;
+ QMediaContent m_media;
+};
+
+class QtTestRendererControl : public QVideoRendererControl
+{
+public:
+ QtTestRendererControl(QObject *parent ) : QVideoRendererControl(parent), m_surface(0) {}
+
+ QAbstractVideoSurface *surface() const { return m_surface; }
+ void setSurface(QAbstractVideoSurface *surface) { m_surface = surface; }
+
+private:
+ QAbstractVideoSurface *m_surface;
+};
+
+class QtTestWindowControl : public QVideoWindowControl
+{
+public:
+ QtTestWindowControl(QObject *parent)
+ : QVideoWindowControl(parent)
+ , m_winId(0)
+ , m_repaintCount(0)
+ , m_brightness(0)
+ , m_contrast(0)
+ , m_saturation(0)
+ , m_aspectRatioMode(Qt::KeepAspectRatio)
+ , m_fullScreen(0)
+ {
+ }
+
+ WId winId() const { return m_winId; }
+ void setWinId(WId id) { m_winId = id; }
+
+ QRect displayRect() const { return m_displayRect; }
+ void setDisplayRect(const QRect &rect) { m_displayRect = rect; }
+
+ bool isFullScreen() const { return m_fullScreen; }
+ void setFullScreen(bool fullScreen) { emit fullScreenChanged(m_fullScreen = fullScreen); }
+
+ int repaintCount() const { return m_repaintCount; }
+ void setRepaintCount(int count) { m_repaintCount = count; }
+ void repaint() { ++m_repaintCount; }
+
+ QSize nativeSize() const { return m_nativeSize; }
+ void setNativeSize(const QSize &size) { m_nativeSize = size; emit nativeSizeChanged(); }
+
+ Qt::AspectRatioMode aspectRatioMode() const { return m_aspectRatioMode; }
+ void setAspectRatioMode(Qt::AspectRatioMode mode) { m_aspectRatioMode = mode; }
+
+ int brightness() const { return m_brightness; }
+ void setBrightness(int brightness) { emit brightnessChanged(m_brightness = brightness); }
+
+ int contrast() const { return m_contrast; }
+ void setContrast(int contrast) { emit contrastChanged(m_contrast = contrast); }
+
+ int hue() const { return m_hue; }
+ void setHue(int hue) { emit hueChanged(m_hue = hue); }
+
+ int saturation() const { return m_saturation; }
+ void setSaturation(int saturation) { emit saturationChanged(m_saturation = saturation); }
+
+private:
+ WId m_winId;
+ int m_repaintCount;
+ int m_brightness;
+ int m_contrast;
+ int m_hue;
+ int m_saturation;
+ Qt::AspectRatioMode m_aspectRatioMode;
+ QRect m_displayRect;
+ QSize m_nativeSize;
+ bool m_fullScreen;
+};
+
+class QtTestMediaService : public QMediaService
+{
+ Q_OBJECT
+public:
+ QtTestMediaService(
+ QtTestMediaPlayerControl *playerControl,
+ QtTestRendererControl *rendererControl,
+ QtTestWindowControl *windowControl,
+ QObject *parent)
+ : QMediaService(parent)
+ , playerControl(playerControl)
+ , rendererControl(rendererControl)
+ , windowControl(windowControl)
+ {
+ }
+
+ QMediaControl *requestControl(const char *name)
+ {
+ if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
+ return playerControl;
+ else if (qstrcmp(name, QVideoRendererControl_iid) == 0)
+ return rendererControl;
+ else if (qstrcmp(name, QVideoWindowControl_iid) == 0)
+ return windowControl;
+ else
+ return 0;
+ }
+
+ void releaseControl(QMediaControl *) {}
+
+ QtTestMediaPlayerControl *playerControl;
+ QtTestRendererControl *rendererControl;
+ QtTestWindowControl *windowControl;
+};
+
+class QtTestMediaServiceProvider : public QMediaServiceProvider
+{
+ Q_OBJECT
+public:
+ QtTestMediaServiceProvider()
+ : service(
+ new QtTestMediaService(
+ new QtTestMediaPlayerControl(this),
+ new QtTestRendererControl(this),
+ new QtTestWindowControl(this),
+ this))
+ {
+ setDefaultServiceProvider(this);
+ }
+
+ QtTestMediaServiceProvider(QtTestMediaService *service)
+ : service(service)
+ {
+ setDefaultServiceProvider(this);
+ }
+
+ QtTestMediaServiceProvider(
+ QtTestMediaPlayerControl *playerControl,
+ QtTestRendererControl *rendererControl,
+ QtTestWindowControl *windowControl)
+ : service(new QtTestMediaService(playerControl, rendererControl, windowControl, this))
+ {
+ setDefaultServiceProvider(this);
+ }
+
+ ~QtTestMediaServiceProvider()
+ {
+ setDefaultServiceProvider(0);
+ }
+
+ QMediaService *requestService(
+ const QByteArray &type,
+ const QMediaServiceProviderHint & = QMediaServiceProviderHint())
+ {
+ requestedService = type;
+
+ return service;
+ }
+
+ void releaseService(QMediaService *) {}
+
+ inline QtTestMediaPlayerControl *playerControl() { return service->playerControl; }
+ inline QtTestRendererControl *rendererControl() { return service->rendererControl; }
+
+ QtTestMediaService *service;
+ QByteArray requestedService;
+};
+
+
+void tst_QDeclarativeVideo::initTestCase()
+{
+ qRegisterMetaType<QDeclarativeVideo::Error>();
+}
+
+void tst_QDeclarativeVideo::nullPlayerControl()
+{
+ QtTestMediaServiceProvider provider(0, 0, 0);
+
+ QDeclarativeVideo video;
+ video.classBegin();
+
+ QCOMPARE(video.source(), QUrl());
+ video.setSource(QUrl("http://example.com"));
+ QCOMPARE(video.source(), QUrl("http://example.com"));
+
+ QCOMPARE(video.isPlaying(), false);
+ video.setPlaying(true);
+ QCOMPARE(video.isPlaying(), true);
+ video.setPlaying(false);
+ video.play();
+ QCOMPARE(video.isPlaying(), false);
+
+ QCOMPARE(video.isPaused(), false);
+ video.pause();
+ QCOMPARE(video.isPaused(), false);
+ video.setPaused(true);
+ QCOMPARE(video.isPaused(), true);
+
+ QCOMPARE(video.duration(), 0);
+
+ QCOMPARE(video.position(), 0);
+ video.setPosition(10000);
+ QCOMPARE(video.position(), 10000);
+
+ QCOMPARE(video.volume(), qreal(1.0));
+ video.setVolume(0.5);
+ QCOMPARE(video.volume(), qreal(0.5));
+
+ QCOMPARE(video.isMuted(), false);
+ video.setMuted(true);
+ QCOMPARE(video.isMuted(), true);
+
+ QCOMPARE(video.bufferProgress(), qreal(0));
+
+ QCOMPARE(video.isSeekable(), false);
+
+ QCOMPARE(video.playbackRate(), qreal(1.0));
+
+ QCOMPARE(video.hasAudio(), false);
+ QCOMPARE(video.hasVideo(), false);
+
+ QCOMPARE(video.status(), QDeclarativeVideo::NoMedia);
+
+ QCOMPARE(video.error(), QDeclarativeVideo::ServiceMissing);
+}
+
+void tst_QDeclarativeVideo::nullService()
+{
+ QtTestMediaServiceProvider provider(0);
+
+ QDeclarativeVideo video;
+ video.classBegin();
+
+ QCOMPARE(video.source(), QUrl());
+ video.setSource(QUrl("http://example.com"));
+ QCOMPARE(video.source(), QUrl("http://example.com"));
+
+ QCOMPARE(video.isPlaying(), false);
+ video.setPlaying(true);
+ QCOMPARE(video.isPlaying(), true);
+ video.setPlaying(false);
+ video.play();
+ QCOMPARE(video.isPlaying(), false);
+
+ QCOMPARE(video.isPaused(), false);
+ video.pause();
+ QCOMPARE(video.isPaused(), false);
+ video.setPaused(true);
+ QCOMPARE(video.isPaused(), true);
+
+ QCOMPARE(video.duration(), 0);
+
+ QCOMPARE(video.position(), 0);
+ video.setPosition(10000);
+ QCOMPARE(video.position(), 10000);
+
+ QCOMPARE(video.volume(), qreal(1.0));
+ video.setVolume(0.5);
+ QCOMPARE(video.volume(), qreal(0.5));
+
+ QCOMPARE(video.isMuted(), false);
+ video.setMuted(true);
+ QCOMPARE(video.isMuted(), true);
+
+ QCOMPARE(video.bufferProgress(), qreal(0));
+
+ QCOMPARE(video.isSeekable(), false);
+
+ QCOMPARE(video.playbackRate(), qreal(1.0));
+
+ QCOMPARE(video.hasAudio(), false);
+ QCOMPARE(video.hasVideo(), false);
+
+ QCOMPARE(video.status(), QDeclarativeVideo::NoMedia);
+
+ QCOMPARE(video.error(), QDeclarativeVideo::ServiceMissing);
+
+ QCOMPARE(video.metaObject()->indexOfProperty("title"), -1);
+ QCOMPARE(video.metaObject()->indexOfProperty("genre"), -1);
+ QCOMPARE(video.metaObject()->indexOfProperty("description"), -1);
+}
+
+void tst_QDeclarativeVideo::playing()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeVideo video;
+ video.classBegin();
+ video.componentComplete();
+ video.setSource(QUrl("http://example.com"));
+
+ QSignalSpy playingChangedSpy(&video, SIGNAL(playingChanged()));
+ QSignalSpy startedSpy(&video, SIGNAL(started()));
+ QSignalSpy stoppedSpy(&video, SIGNAL(stopped()));
+
+ int playingChanged = 0;
+ int started = 0;
+ int stopped = 0;
+
+ QCOMPARE(video.isPlaying(), false);
+
+ // setPlaying(true) when stopped.
+ video.setPlaying(true);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when playing.
+ video.setPlaying(false);
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // play() when stopped.
+ video.play();
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // stop() when playing.
+ video.stop();
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // stop() when stopped.
+ video.stop();
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when stopped.
+ video.setPlaying(false);
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ video.setPlaying(true);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(true) when playing.
+ video.setPlaying(true);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // play() when playing.
+ video.play();
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(stoppedSpy.count(), stopped);
+}
+
+void tst_QDeclarativeVideo::paused()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeVideo video;
+ video.classBegin();
+ video.componentComplete();
+ video.setSource(QUrl("http://example.com"));
+
+ QSignalSpy playingChangedSpy(&video, SIGNAL(playingChanged()));
+ QSignalSpy pausedChangedSpy(&video, SIGNAL(pausedChanged()));
+ QSignalSpy startedSpy(&video, SIGNAL(started()));
+ QSignalSpy pausedSpy(&video, SIGNAL(paused()));
+ QSignalSpy resumedSpy(&video, SIGNAL(resumed()));
+ QSignalSpy stoppedSpy(&video, SIGNAL(stopped()));
+
+ int playingChanged = 0;
+ int pausedChanged = 0;
+ int started = 0;
+ int paused = 0;
+ int resumed = 0;
+ int stopped = 0;
+
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), false);
+
+ // setPlaying(true) when stopped.
+ video.setPlaying(true);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(true) when playing.
+ video.setPaused(true);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(true) when paused.
+ video.setPaused(true);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // pause() when paused.
+ video.pause();
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(false) when paused.
+ video.setPaused(false);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), ++resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(false) when playing.
+ video.setPaused(false);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // pause() when playing.
+ video.pause();
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when paused.
+ video.setPlaying(false);
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // setPaused(true) when stopped and paused.
+ video.setPaused(true);
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(false) when stopped and paused.
+ video.setPaused(false);
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(true) when stopped.
+ video.setPaused(true);
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(true) when stopped and paused.
+ video.setPlaying(true);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // play() when paused.
+ video.play();
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), ++resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPaused(true) when playing.
+ video.setPaused(true);
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // stop() when paused.
+ video.stop();
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // setPaused(true) when stopped.
+ video.setPaused(true);
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // stop() when stopped and paused.
+ video.stop();
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // pause() when stopped.
+ video.pause();
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when paused.
+ video.setPlaying(false);
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // pause() when stopped and paused.
+ video.pause();
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), ++paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+
+ // setPlaying(false) when paused.
+ video.setPlaying(false);
+ QCOMPARE(video.isPlaying(), false);
+ QCOMPARE(video.isPaused(), true);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), pausedChanged);
+ QCOMPARE(startedSpy.count(), started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), ++stopped);
+
+ // play() when stopped and paused.
+ video.play();
+ QCOMPARE(video.isPlaying(), true);
+ QCOMPARE(video.isPaused(), false);
+ QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(playingChangedSpy.count(), ++playingChanged);
+ QCOMPARE(pausedChangedSpy.count(), ++pausedChanged);
+ QCOMPARE(startedSpy.count(), ++started);
+ QCOMPARE(pausedSpy.count(), paused);
+ QCOMPARE(resumedSpy.count(), resumed);
+ QCOMPARE(stoppedSpy.count(), stopped);
+}
+
+void tst_QDeclarativeVideo::error()
+{
+ const QString errorString = QLatin1String("Failed to open device.");
+
+ QtTestMediaServiceProvider provider;
+ QDeclarativeVideo video;
+ video.classBegin();
+ video.componentComplete();
+
+ QSignalSpy errorSpy(&video, SIGNAL(error(QDeclarativeVideo::Error,QString)));
+ QSignalSpy errorChangedSpy(&video, SIGNAL(errorChanged()));
+
+ QCOMPARE(video.error(), QDeclarativeVideo::NoError);
+ QCOMPARE(video.errorString(), QString());
+
+ provider.playerControl()->emitError(QMediaPlayer::ResourceError, errorString);
+
+ QCOMPARE(video.error(), QDeclarativeVideo::ResourceError);
+ QCOMPARE(video.errorString(), errorString);
+ QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorChangedSpy.count(), 1);
+
+ // Changing the source resets the error properties.
+ video.setSource(QUrl("http://example.com"));
+ QCOMPARE(video.error(), QDeclarativeVideo::NoError);
+ QCOMPARE(video.errorString(), QString());
+ QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorChangedSpy.count(), 2);
+
+ // But isn't noisy.
+ video.setSource(QUrl("file:///file/path"));
+ QCOMPARE(video.error(), QDeclarativeVideo::NoError);
+ QCOMPARE(video.errorString(), QString());
+ QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorChangedSpy.count(), 2);
+}
+
+
+void tst_QDeclarativeVideo::hasAudio()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeVideo video;
+ video.classBegin();
+ video.componentComplete();
+
+ QSignalSpy spy(&video, SIGNAL(hasAudioChanged()));
+
+ QCOMPARE(video.hasAudio(), false);
+
+ provider.playerControl()->setAudioAvailable(true);
+ QCOMPARE(video.hasAudio(), true);
+ QCOMPARE(spy.count(), 1);
+
+ provider.playerControl()->setAudioAvailable(true);
+ QCOMPARE(video.hasAudio(), true);
+ QCOMPARE(spy.count(), 2);
+
+ provider.playerControl()->setAudioAvailable(false);
+ QCOMPARE(video.hasAudio(), false);
+ QCOMPARE(spy.count(), 3);
+}
+
+void tst_QDeclarativeVideo::hasVideo()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeVideo video;
+ video.classBegin();
+ video.componentComplete();
+
+ QSignalSpy spy(&video, SIGNAL(hasVideoChanged()));
+
+ QCOMPARE(video.hasVideo(), false);
+
+ provider.playerControl()->setVideoAvailable(true);
+ QCOMPARE(video.hasVideo(), true);
+ QCOMPARE(spy.count(), 1);
+
+ provider.playerControl()->setVideoAvailable(true);
+ QCOMPARE(video.hasVideo(), true);
+ QCOMPARE(spy.count(), 2);
+
+ provider.playerControl()->setVideoAvailable(false);
+ QCOMPARE(video.hasVideo(), false);
+ QCOMPARE(spy.count(), 3);
+}
+
+void tst_QDeclarativeVideo::fillMode()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeVideo video;
+ video.classBegin();
+ video.componentComplete();
+
+ QList<QGraphicsItem *> children = video.childItems();
+ QCOMPARE(children.count(), 1);
+ QGraphicsVideoItem *videoItem = qgraphicsitem_cast<QGraphicsVideoItem *>(children.first());
+ QVERIFY(videoItem != 0);
+
+ QCOMPARE(video.fillMode(), QDeclarativeVideo::PreserveAspectFit);
+
+ video.setFillMode(QDeclarativeVideo::PreserveAspectCrop);
+ QCOMPARE(video.fillMode(), QDeclarativeVideo::PreserveAspectCrop);
+ QCOMPARE(videoItem->aspectRatioMode(), Qt::KeepAspectRatioByExpanding);
+
+ video.setFillMode(QDeclarativeVideo::Stretch);
+ QCOMPARE(video.fillMode(), QDeclarativeVideo::Stretch);
+ QCOMPARE(videoItem->aspectRatioMode(), Qt::IgnoreAspectRatio);
+
+ video.setFillMode(QDeclarativeVideo::PreserveAspectFit);
+ QCOMPARE(video.fillMode(), QDeclarativeVideo::PreserveAspectFit);
+ QCOMPARE(videoItem->aspectRatioMode(), Qt::KeepAspectRatio);
+}
+
+void tst_QDeclarativeVideo::geometry()
+{
+ QtTestMediaServiceProvider provider;
+ QDeclarativeVideo video;
+ video.classBegin();
+ video.componentComplete();
+
+ QList<QGraphicsItem *> children = video.childItems();
+ QCOMPARE(children.count(), 1);
+ QGraphicsVideoItem *videoItem = qgraphicsitem_cast<QGraphicsVideoItem *>(children.first());
+ QVERIFY(videoItem != 0);
+
+ { // Surface setup is deferred until after the first paint.
+ QImage image(320, 240, QImage::Format_RGB32);
+ QPainter painter(&image);
+
+ videoItem->paint(&painter, 0);
+ }
+
+ QAbstractVideoSurface *surface = provider.rendererControl()->surface();
+
+ //video item can use overlay, QAbstractVideoSurface is not used than.
+ if (surface) {
+ QVideoSurfaceFormat format(QSize(640, 480), QVideoFrame::Format_RGB32);
+
+ QVERIFY(surface->start(format));
+ QCoreApplication::processEvents();
+
+ QCOMPARE(video.implicitWidth(), qreal(640));
+ QCOMPARE(video.implicitHeight(), qreal(480));
+ }
+
+ video.setWidth(560);
+ video.setHeight(328);
+
+ QCOMPARE(videoItem->size().width(), qreal(560));
+ QCOMPARE(videoItem->size().height(), qreal(328));
+}
+
+QTEST_MAIN(tst_QDeclarativeVideo)
+
+#include "tst_qdeclarativevideo.moc"
diff --git a/tests/auto/qgraphicsvideoitem/qgraphicsvideoitem.pro b/tests/auto/qgraphicsvideoitem/qgraphicsvideoitem.pro
new file mode 100644
index 000000000..1d8735d42
--- /dev/null
+++ b/tests/auto/qgraphicsvideoitem/qgraphicsvideoitem.pro
@@ -0,0 +1,12 @@
+load(qttest_p4)
+
+QT += multimediakit-private
+
+# TARGET = tst_qgraphicsvideoitem
+# CONFIG += testcase
+
+SOURCES += tst_qgraphicsvideoitem.cpp
+
+symbian: TARGET.CAPABILITY = ReadDeviceData WriteDeviceData
+
+maemo*:CONFIG += insignificant_test
diff --git a/tests/auto/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp b/tests/auto/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp
new file mode 100644
index 000000000..2e7b97df8
--- /dev/null
+++ b/tests/auto/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp
@@ -0,0 +1,675 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include <qmobilityglobal.h>
+#include "qgraphicsvideoitem.h"
+#include <QtTest/QtTest>
+#include "qmediaobject.h"
+#include "qmediaservice.h"
+#include <private/qpaintervideosurface_p.h>
+#include "qvideorenderercontrol.h"
+
+#include <qabstractvideosurface.h>
+#include <qvideosurfaceformat.h>
+
+#include <QtGui/qapplication.h>
+#include <QtGui/qgraphicsscene.h>
+#include <QtGui/qgraphicsview.h>
+
+QT_USE_NAMESPACE
+class tst_QGraphicsVideoItem : public QObject
+{
+ Q_OBJECT
+public slots:
+ void initTestCase();
+
+private slots:
+ void nullObject();
+ void nullService();
+ void noOutputs();
+ void serviceDestroyed();
+ void mediaObjectDestroyed();
+ void setMediaObject();
+
+ void show();
+
+ void aspectRatioMode();
+ void offset();
+ void size();
+ void nativeSize_data();
+ void nativeSize();
+
+ void boundingRect_data();
+ void boundingRect();
+
+ void paint();
+};
+
+Q_DECLARE_METATYPE(const uchar *)
+Q_DECLARE_METATYPE(Qt::AspectRatioMode)
+
+class QtTestRendererControl : public QVideoRendererControl
+{
+public:
+ QtTestRendererControl()
+ : m_surface(0)
+ {
+ }
+
+ QAbstractVideoSurface *surface() const { return m_surface; }
+ void setSurface(QAbstractVideoSurface *surface) { m_surface = surface; }
+
+private:
+ QAbstractVideoSurface *m_surface;
+};
+
+class QtTestVideoService : public QMediaService
+{
+ Q_OBJECT
+public:
+ QtTestVideoService(
+ QtTestRendererControl *renderer)
+ : QMediaService(0)
+ , rendererRef(0)
+ , rendererControl(renderer)
+ {
+ }
+
+ ~QtTestVideoService()
+ {
+ delete rendererControl;
+ }
+
+ QMediaControl *requestControl(const char *name)
+ {
+ if (qstrcmp(name, QVideoRendererControl_iid) == 0 && rendererControl) {
+ rendererRef += 1;
+
+ return rendererControl;
+ } else {
+ return 0;
+ }
+ }
+
+ void releaseControl(QMediaControl *control)
+ {
+ Q_ASSERT(control);
+
+ if (control == rendererControl) {
+ rendererRef -= 1;
+
+ if (rendererRef == 0)
+ rendererControl->setSurface(0);
+ }
+ }
+
+ int rendererRef;
+ QtTestRendererControl *rendererControl;
+};
+
+class QtTestVideoObject : public QMediaObject
+{
+ Q_OBJECT
+public:
+ QtTestVideoObject(QtTestRendererControl *renderer)
+ : QMediaObject(0, new QtTestVideoService(renderer))
+ {
+ testService = qobject_cast<QtTestVideoService*>(service());
+ }
+
+ QtTestVideoObject(QtTestVideoService *service):
+ QMediaObject(0, service),
+ testService(service)
+ {
+ }
+
+ ~QtTestVideoObject()
+ {
+ delete testService;
+ }
+
+ QtTestVideoService *testService;
+};
+
+class QtTestGraphicsVideoItem : public QGraphicsVideoItem
+{
+public:
+ QtTestGraphicsVideoItem(QGraphicsItem *parent = 0)
+ : QGraphicsVideoItem(parent)
+ , m_paintCount(0)
+ {
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ ++m_paintCount;
+
+ QTestEventLoop::instance().exitLoop();
+
+ QGraphicsVideoItem::paint(painter, option, widget);
+ }
+
+ bool waitForPaint(int secs)
+ {
+ const int paintCount = m_paintCount;
+
+ QTestEventLoop::instance().enterLoop(secs);
+
+ return m_paintCount != paintCount;
+ }
+
+ int paintCount() const
+ {
+ return m_paintCount;
+ }
+
+private:
+ int m_paintCount;
+};
+
+void tst_QGraphicsVideoItem::initTestCase()
+{
+ qRegisterMetaType<Qt::AspectRatioMode>();
+}
+
+void tst_QGraphicsVideoItem::nullObject()
+{
+ QGraphicsVideoItem item(0);
+
+ QVERIFY(item.boundingRect().isEmpty());
+}
+
+void tst_QGraphicsVideoItem::nullService()
+{
+ QtTestVideoService *service = 0;
+
+ QtTestVideoObject object(service);
+
+ QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem;
+ object.bind(item);
+
+ QVERIFY(item->boundingRect().isEmpty());
+
+ item->hide();
+ item->show();
+
+ QGraphicsScene graphicsScene;
+ graphicsScene.addItem(item);
+ QGraphicsView graphicsView(&graphicsScene);
+ graphicsView.show();
+}
+
+void tst_QGraphicsVideoItem::noOutputs()
+{
+ QtTestRendererControl *control = 0;
+ QtTestVideoObject object(control);
+
+ QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem;
+ object.bind(item);
+
+ QVERIFY(item->boundingRect().isEmpty());
+
+ item->hide();
+ item->show();
+
+ QGraphicsScene graphicsScene;
+ graphicsScene.addItem(item);
+ QGraphicsView graphicsView(&graphicsScene);
+ graphicsView.show();
+}
+
+void tst_QGraphicsVideoItem::serviceDestroyed()
+{
+ QtTestVideoObject object(new QtTestRendererControl);
+
+ QGraphicsVideoItem item;
+ object.bind(&item);
+
+ QCOMPARE(object.testService->rendererRef, 1);
+
+ QtTestVideoService *service = object.testService;
+ object.testService = 0;
+
+ delete service;
+
+ QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(&object));
+ QVERIFY(item.boundingRect().isEmpty());
+}
+
+void tst_QGraphicsVideoItem::mediaObjectDestroyed()
+{
+ QtTestVideoObject *object = new QtTestVideoObject(new QtTestRendererControl);
+
+ QGraphicsVideoItem item;
+ object->bind(&item);
+
+ QCOMPARE(object->testService->rendererRef, 1);
+
+ delete object;
+ object = 0;
+
+ QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(object));
+ QVERIFY(item.boundingRect().isEmpty());
+}
+
+void tst_QGraphicsVideoItem::setMediaObject()
+{
+ QMediaObject *nullObject = 0;
+ QtTestVideoObject object(new QtTestRendererControl);
+
+ QGraphicsVideoItem item;
+
+ QCOMPARE(item.mediaObject(), nullObject);
+ QCOMPARE(object.testService->rendererRef, 0);
+
+ object.bind(&item);
+ QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(&object));
+ QCOMPARE(object.testService->rendererRef, 1);
+ QVERIFY(object.testService->rendererControl->surface() == 0);
+
+ { // Surface setup is deferred until after the first paint.
+ QImage image(320, 240, QImage::Format_RGB32);
+ QPainter painter(&image);
+
+ item.paint(&painter, 0);
+ }
+ QVERIFY(object.testService->rendererControl->surface() != 0);
+
+ object.unbind(&item);
+ QCOMPARE(item.mediaObject(), nullObject);
+
+ QCOMPARE(object.testService->rendererRef, 0);
+ QVERIFY(object.testService->rendererControl->surface() == 0);
+
+ item.setVisible(false);
+
+ object.bind(&item);
+ QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(&object));
+ QCOMPARE(object.testService->rendererRef, 1);
+ QVERIFY(object.testService->rendererControl->surface() != 0);
+}
+
+void tst_QGraphicsVideoItem::show()
+{
+ QtTestVideoObject object(new QtTestRendererControl);
+ QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem;
+ object.bind(item);
+
+ // Graphics items are visible by default
+ QCOMPARE(object.testService->rendererRef, 1);
+ QVERIFY(object.testService->rendererControl->surface() == 0);
+
+ item->hide();
+ QCOMPARE(object.testService->rendererRef, 1);
+
+ item->show();
+ QCOMPARE(object.testService->rendererRef, 1);
+ QVERIFY(object.testService->rendererControl->surface() == 0);
+
+ QGraphicsScene graphicsScene;
+ graphicsScene.addItem(item);
+ QGraphicsView graphicsView(&graphicsScene);
+ graphicsView.show();
+
+ QVERIFY(item->paintCount() || item->waitForPaint(1));
+ QVERIFY(object.testService->rendererControl->surface() != 0);
+
+ QVERIFY(item->boundingRect().isEmpty());
+
+ QVideoSurfaceFormat format(QSize(320,240),QVideoFrame::Format_RGB32);
+ QVERIFY(object.testService->rendererControl->surface()->start(format));
+
+ QCoreApplication::processEvents();
+ QVERIFY(!item->boundingRect().isEmpty());
+}
+
+void tst_QGraphicsVideoItem::aspectRatioMode()
+{
+ QGraphicsVideoItem item;
+
+ QCOMPARE(item.aspectRatioMode(), Qt::KeepAspectRatio);
+
+ item.setAspectRatioMode(Qt::IgnoreAspectRatio);
+ QCOMPARE(item.aspectRatioMode(), Qt::IgnoreAspectRatio);
+
+ item.setAspectRatioMode(Qt::KeepAspectRatioByExpanding);
+ QCOMPARE(item.aspectRatioMode(), Qt::KeepAspectRatioByExpanding);
+
+ item.setAspectRatioMode(Qt::KeepAspectRatio);
+ QCOMPARE(item.aspectRatioMode(), Qt::KeepAspectRatio);
+}
+
+void tst_QGraphicsVideoItem::offset()
+{
+ QGraphicsVideoItem item;
+
+ QCOMPARE(item.offset(), QPointF(0, 0));
+
+ item.setOffset(QPointF(-32.4, 43.0));
+ QCOMPARE(item.offset(), QPointF(-32.4, 43.0));
+
+ item.setOffset(QPointF(1, 1));
+ QCOMPARE(item.offset(), QPointF(1, 1));
+
+ item.setOffset(QPointF(12, -30.4));
+ QCOMPARE(item.offset(), QPointF(12, -30.4));
+
+ item.setOffset(QPointF(-90.4, -75));
+ QCOMPARE(item.offset(), QPointF(-90.4, -75));
+}
+
+void tst_QGraphicsVideoItem::size()
+{
+ QGraphicsVideoItem item;
+
+ QCOMPARE(item.size(), QSizeF(320, 240));
+
+ item.setSize(QSizeF(542.5, 436.3));
+ QCOMPARE(item.size(), QSizeF(542.5, 436.3));
+
+ item.setSize(QSizeF(-43, 12));
+ QCOMPARE(item.size(), QSizeF(0, 0));
+
+ item.setSize(QSizeF(54, -9));
+ QCOMPARE(item.size(), QSizeF(0, 0));
+
+ item.setSize(QSizeF(-90, -65));
+ QCOMPARE(item.size(), QSizeF(0, 0));
+
+ item.setSize(QSizeF(1000, 1000));
+ QCOMPARE(item.size(), QSizeF(1000, 1000));
+}
+
+void tst_QGraphicsVideoItem::nativeSize_data()
+{
+ QTest::addColumn<QSize>("frameSize");
+ QTest::addColumn<QRect>("viewport");
+ QTest::addColumn<QSize>("pixelAspectRatio");
+ QTest::addColumn<QSizeF>("nativeSize");
+
+ QTest::newRow("640x480")
+ << QSize(640, 480)
+ << QRect(0, 0, 640, 480)
+ << QSize(1, 1)
+ << QSizeF(640, 480);
+
+ QTest::newRow("800x600, (80,60, 640x480) viewport")
+ << QSize(800, 600)
+ << QRect(80, 60, 640, 480)
+ << QSize(1, 1)
+ << QSizeF(640, 480);
+
+ QTest::newRow("800x600, (80,60, 640x480) viewport, 4:3")
+ << QSize(800, 600)
+ << QRect(80, 60, 640, 480)
+ << QSize(4, 3)
+ << QSizeF(853, 480);
+}
+
+void tst_QGraphicsVideoItem::nativeSize()
+{
+ QFETCH(QSize, frameSize);
+ QFETCH(QRect, viewport);
+ QFETCH(QSize, pixelAspectRatio);
+ QFETCH(QSizeF, nativeSize);
+
+ QtTestVideoObject object(new QtTestRendererControl);
+ QGraphicsVideoItem item;
+ object.bind(&item);
+
+ QCOMPARE(item.nativeSize(), QSizeF());
+
+ QSignalSpy spy(&item, SIGNAL(nativeSizeChanged(QSizeF)));
+
+ QVideoSurfaceFormat format(frameSize, QVideoFrame::Format_ARGB32);
+ format.setViewport(viewport);
+ format.setPixelAspectRatio(pixelAspectRatio);
+
+ { // Surface setup is deferred until after the first paint.
+ QImage image(320, 240, QImage::Format_RGB32);
+ QPainter painter(&image);
+
+ item.paint(&painter, 0);
+ }
+ QVERIFY(object.testService->rendererControl->surface() != 0);
+ QVERIFY(object.testService->rendererControl->surface()->start(format));
+
+ QCoreApplication::processEvents();
+ QCOMPARE(item.nativeSize(), nativeSize);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.last().first().toSizeF(), nativeSize);
+
+ object.testService->rendererControl->surface()->stop();
+
+ QCoreApplication::processEvents();
+ QVERIFY(item.nativeSize().isEmpty());
+ QCOMPARE(spy.count(), 2);
+ QVERIFY(spy.last().first().toSizeF().isEmpty());
+}
+
+void tst_QGraphicsVideoItem::boundingRect_data()
+{
+ QTest::addColumn<QSize>("frameSize");
+ QTest::addColumn<QPointF>("offset");
+ QTest::addColumn<QSizeF>("size");
+ QTest::addColumn<Qt::AspectRatioMode>("aspectRatioMode");
+ QTest::addColumn<QRectF>("expectedRect");
+
+
+ QTest::newRow("640x480: (0,0 640x480), Keep")
+ << QSize(640, 480)
+ << QPointF(0, 0)
+ << QSizeF(640, 480)
+ << Qt::KeepAspectRatio
+ << QRectF(0, 0, 640, 480);
+
+ QTest::newRow("800x600, (0,0, 640x480), Keep")
+ << QSize(800, 600)
+ << QPointF(0, 0)
+ << QSizeF(640, 480)
+ << Qt::KeepAspectRatio
+ << QRectF(0, 0, 640, 480);
+
+ QTest::newRow("800x600, (0,0, 640x480), KeepByExpanding")
+ << QSize(800, 600)
+ << QPointF(0, 0)
+ << QSizeF(640, 480)
+ << Qt::KeepAspectRatioByExpanding
+ << QRectF(0, 0, 640, 480);
+
+ QTest::newRow("800x600, (0,0, 640x480), Ignore")
+ << QSize(800, 600)
+ << QPointF(0, 0)
+ << QSizeF(640, 480)
+ << Qt::IgnoreAspectRatio
+ << QRectF(0, 0, 640, 480);
+
+ QTest::newRow("800x600, (100,100, 640x480), Keep")
+ << QSize(800, 600)
+ << QPointF(100, 100)
+ << QSizeF(640, 480)
+ << Qt::KeepAspectRatio
+ << QRectF(100, 100, 640, 480);
+
+ QTest::newRow("800x600, (100,-100, 640x480), KeepByExpanding")
+ << QSize(800, 600)
+ << QPointF(100, -100)
+ << QSizeF(640, 480)
+ << Qt::KeepAspectRatioByExpanding
+ << QRectF(100, -100, 640, 480);
+
+ QTest::newRow("800x600, (-100,-100, 640x480), Ignore")
+ << QSize(800, 600)
+ << QPointF(-100, -100)
+ << QSizeF(640, 480)
+ << Qt::IgnoreAspectRatio
+ << QRectF(-100, -100, 640, 480);
+
+ QTest::newRow("800x600, (0,0, 1920x1024), Keep")
+ << QSize(800, 600)
+ << QPointF(0, 0)
+ << QSizeF(1920, 1024)
+ << Qt::KeepAspectRatio
+ << QRectF(832.0 / 3, 0, 4096.0 / 3, 1024);
+
+ QTest::newRow("800x600, (0,0, 1920x1024), KeepByExpanding")
+ << QSize(800, 600)
+ << QPointF(0, 0)
+ << QSizeF(1920, 1024)
+ << Qt::KeepAspectRatioByExpanding
+ << QRectF(0, 0, 1920, 1024);
+
+ QTest::newRow("800x600, (0,0, 1920x1024), Ignore")
+ << QSize(800, 600)
+ << QPointF(0, 0)
+ << QSizeF(1920, 1024)
+ << Qt::IgnoreAspectRatio
+ << QRectF(0, 0, 1920, 1024);
+
+ QTest::newRow("800x600, (100,100, 1920x1024), Keep")
+ << QSize(800, 600)
+ << QPointF(100, 100)
+ << QSizeF(1920, 1024)
+ << Qt::KeepAspectRatio
+ << QRectF(100 + 832.0 / 3, 100, 4096.0 / 3, 1024);
+
+ QTest::newRow("800x600, (100,-100, 1920x1024), KeepByExpanding")
+ << QSize(800, 600)
+ << QPointF(100, -100)
+ << QSizeF(1920, 1024)
+ << Qt::KeepAspectRatioByExpanding
+ << QRectF(100, -100, 1920, 1024);
+
+ QTest::newRow("800x600, (-100,-100, 1920x1024), Ignore")
+ << QSize(800, 600)
+ << QPointF(-100, -100)
+ << QSizeF(1920, 1024)
+ << Qt::IgnoreAspectRatio
+ << QRectF(-100, -100, 1920, 1024);
+}
+
+void tst_QGraphicsVideoItem::boundingRect()
+{
+ QFETCH(QSize, frameSize);
+ QFETCH(QPointF, offset);
+ QFETCH(QSizeF, size);
+ QFETCH(Qt::AspectRatioMode, aspectRatioMode);
+ QFETCH(QRectF, expectedRect);
+
+ QtTestVideoObject object(new QtTestRendererControl);
+ QGraphicsVideoItem item;
+ object.bind(&item);
+
+ item.setOffset(offset);
+ item.setSize(size);
+ item.setAspectRatioMode(aspectRatioMode);
+
+ QVideoSurfaceFormat format(frameSize, QVideoFrame::Format_ARGB32);
+
+ { // Surface setup is deferred until after the first paint.
+ QImage image(320, 240, QImage::Format_RGB32);
+ QPainter painter(&image);
+
+ item.paint(&painter, 0);
+ }
+ QVERIFY(object.testService->rendererControl->surface() != 0);
+ QVERIFY(object.testService->rendererControl->surface()->start(format));
+
+ QCoreApplication::processEvents();
+ QCOMPARE(item.boundingRect(), expectedRect);
+}
+
+static const uchar rgb32ImageData[] =
+{
+ 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00
+};
+
+void tst_QGraphicsVideoItem::paint()
+{
+ QtTestVideoObject object(new QtTestRendererControl);
+ QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem;
+ object.bind(item);
+
+ QGraphicsScene graphicsScene;
+ graphicsScene.addItem(item);
+ QGraphicsView graphicsView(&graphicsScene);
+ graphicsView.show();
+ QVERIFY(item->waitForPaint(1));
+
+ QPainterVideoSurface *surface = qobject_cast<QPainterVideoSurface *>(
+ object.testService->rendererControl->surface());
+ if (!surface)
+ QSKIP("QGraphicsVideoItem is not QPainterVideoSurface based", SkipAll);
+
+ QVideoSurfaceFormat format(QSize(2, 2), QVideoFrame::Format_RGB32);
+
+ QVERIFY(surface->start(format));
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+
+ QVERIFY(item->waitForPaint(1));
+
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+
+ QVideoFrame frame(sizeof(rgb32ImageData), QSize(2, 2), 8, QVideoFrame::Format_RGB32);
+
+ frame.map(QAbstractVideoBuffer::WriteOnly);
+ memcpy(frame.bits(), rgb32ImageData, frame.mappedBytes());
+ frame.unmap();
+
+ QVERIFY(surface->present(frame));
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), false);
+
+ QVERIFY(item->waitForPaint(1));
+
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+}
+
+
+QTEST_MAIN(tst_QGraphicsVideoItem)
+
+#include "tst_qgraphicsvideoitem.moc"
diff --git a/tests/auto/qmediacontent/qmediacontent.pro b/tests/auto/qmediacontent/qmediacontent.pro
new file mode 100644
index 000000000..47d9cea67
--- /dev/null
+++ b/tests/auto/qmediacontent/qmediacontent.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+
+QT += multimediakit-private network
+# TARGET = tst_qmediacontent
+# CONFIG += testcase
+
+SOURCES += tst_qmediacontent.cpp
diff --git a/tests/auto/qmediacontent/tst_qmediacontent.cpp b/tests/auto/qmediacontent/tst_qmediacontent.cpp
new file mode 100644
index 000000000..b350cf175
--- /dev/null
+++ b/tests/auto/qmediacontent/tst_qmediacontent.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtNetwork/qnetworkrequest.h>
+
+#include <qmediacontent.h>
+
+//TESTED_COMPONENT=src/multimedia
+
+QT_USE_NAMESPACE
+class tst_QMediaContent : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void testNull();
+ void testUrlCtor();
+ void testRequestCtor();
+ void testResourceCtor();
+ void testResourceListCtor();
+ void testCopy();
+ void testAssignment();
+ void testEquality();
+ void testResources();
+};
+
+void tst_QMediaContent::testNull()
+{
+ QMediaContent media;
+
+ QCOMPARE(media.isNull(), true);
+ QCOMPARE(media.canonicalUrl(), QUrl());
+ QCOMPARE(media.canonicalResource(), QMediaResource());
+ QCOMPARE(media.resources(), QMediaResourceList());
+}
+
+void tst_QMediaContent::testUrlCtor()
+{
+ QMediaContent media(QUrl("http://example.com/movie.mov"));
+
+ QCOMPARE(media.canonicalUrl(), QUrl("http://example.com/movie.mov"));
+ QCOMPARE(media.canonicalResource().url(), QUrl("http://example.com/movie.mov"));
+}
+
+void tst_QMediaContent::testRequestCtor()
+{
+ QNetworkRequest request(QUrl("http://example.com/movie.mov"));
+ request.setAttribute(QNetworkRequest::User, QVariant(1234));
+
+ QMediaContent media(request);
+
+ QCOMPARE(media.canonicalUrl(), QUrl("http://example.com/movie.mov"));
+ QCOMPARE(media.canonicalResource().request(), request);
+ QCOMPARE(media.canonicalResource().url(), QUrl("http://example.com/movie.mov"));
+}
+
+void tst_QMediaContent::testResourceCtor()
+{
+ QMediaContent media(QMediaResource(QUrl("http://example.com/movie.mov")));
+
+ QCOMPARE(media.canonicalResource(), QMediaResource(QUrl("http://example.com/movie.mov")));
+}
+
+void tst_QMediaContent::testResourceListCtor()
+{
+ QMediaResourceList resourceList;
+ resourceList << QMediaResource(QUrl("http://example.com/movie.mov"));
+
+ QMediaContent media(resourceList);
+
+ QCOMPARE(media.canonicalUrl(), QUrl("http://example.com/movie.mov"));
+ QCOMPARE(media.canonicalResource().url(), QUrl("http://example.com/movie.mov"));
+}
+
+void tst_QMediaContent::testCopy()
+{
+ QMediaContent media1(QMediaResource(QUrl("http://example.com/movie.mov")));
+ QMediaContent media2(media1);
+
+ QVERIFY(media1 == media2);
+}
+
+void tst_QMediaContent::testAssignment()
+{
+ QMediaContent media1(QMediaResource(QUrl("http://example.com/movie.mov")));
+ QMediaContent media2;
+ QMediaContent media3;
+
+ media2 = media1;
+ QVERIFY(media2 == media1);
+
+ media2 = media3;
+ QVERIFY(media2 == media3);
+}
+
+void tst_QMediaContent::testEquality()
+{
+ QMediaContent media1;
+ QMediaContent media2;
+ QMediaContent media3(QMediaResource(QUrl("http://example.com/movie.mov")));
+ QMediaContent media4(QMediaResource(QUrl("http://example.com/movie.mov")));
+ QMediaContent media5(QMediaResource(QUrl("file:///some/where/over/the/rainbow.mp3")));
+
+ // null == null
+ QCOMPARE(media1 == media2, true);
+ QCOMPARE(media1 != media2, false);
+
+ // null != something
+ QCOMPARE(media1 == media3, false);
+ QCOMPARE(media1 != media3, true);
+
+ // equiv
+ QCOMPARE(media3 == media4, true);
+ QCOMPARE(media3 != media4, false);
+
+ // not equiv
+ QCOMPARE(media4 == media5, false);
+ QCOMPARE(media4 != media5, true);
+}
+
+void tst_QMediaContent::testResources()
+{
+ QMediaResourceList resourceList;
+
+ resourceList << QMediaResource(QUrl("http://example.com/movie-main.mov"));
+ resourceList << QMediaResource(QUrl("http://example.com/movie-big.mov"));
+ QMediaContent media(resourceList);
+
+ QMediaResourceList res = media.resources();
+ QCOMPARE(res.size(), 2);
+ QCOMPARE(res[0], QMediaResource(QUrl("http://example.com/movie-main.mov")));
+ QCOMPARE(res[1], QMediaResource(QUrl("http://example.com/movie-big.mov")));
+}
+
+QTEST_MAIN(tst_QMediaContent)
+
+#include "tst_qmediacontent.moc"
diff --git a/tests/auto/qmediaimageviewer/images.qrc b/tests/auto/qmediaimageviewer/images.qrc
new file mode 100644
index 000000000..508de1369
--- /dev/null
+++ b/tests/auto/qmediaimageviewer/images.qrc
@@ -0,0 +1,9 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/coverart.png</file>
+ <file>images/image.jpg</file>
+ <file>images/image.png</file>
+ <file>images/invalid.png</file>
+ <file>images/poster.png</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/qmediaimageviewer/images/coverart.png b/tests/auto/qmediaimageviewer/images/coverart.png
new file mode 100644
index 000000000..a24db1b13
--- /dev/null
+++ b/tests/auto/qmediaimageviewer/images/coverart.png
Binary files differ
diff --git a/tests/auto/qmediaimageviewer/images/image.jpg b/tests/auto/qmediaimageviewer/images/image.jpg
new file mode 100644
index 000000000..8771224cb
--- /dev/null
+++ b/tests/auto/qmediaimageviewer/images/image.jpg
Binary files differ
diff --git a/tests/auto/qmediaimageviewer/images/image.png b/tests/auto/qmediaimageviewer/images/image.png
new file mode 100644
index 000000000..a24db1b13
--- /dev/null
+++ b/tests/auto/qmediaimageviewer/images/image.png
Binary files differ
diff --git a/tests/auto/qmediaimageviewer/images/invalid.png b/tests/auto/qmediaimageviewer/images/invalid.png
new file mode 100644
index 000000000..3aba327ee
--- /dev/null
+++ b/tests/auto/qmediaimageviewer/images/invalid.png
@@ -0,0 +1,2 @@
+This is not really a PNG file.
+
diff --git a/tests/auto/qmediaimageviewer/images/poster.png b/tests/auto/qmediaimageviewer/images/poster.png
new file mode 100644
index 000000000..a24db1b13
--- /dev/null
+++ b/tests/auto/qmediaimageviewer/images/poster.png
Binary files differ
diff --git a/tests/auto/qmediaimageviewer/qmediaimageviewer.pro b/tests/auto/qmediaimageviewer/qmediaimageviewer.pro
new file mode 100644
index 000000000..dab1d2462
--- /dev/null
+++ b/tests/auto/qmediaimageviewer/qmediaimageviewer.pro
@@ -0,0 +1,17 @@
+load(qttest_p4)
+
+QT += multimediakit-private network
+
+# TARGET = tst_qmediaimageviewer
+# CONFIG += testcase
+
+SOURCES += tst_qmediaimageviewer.cpp
+
+RESOURCES += \
+ images.qrc
+
+!contains(QT_CONFIG, no-jpeg):DEFINES += QTEST_HAVE_JPEG
+
+wince* {
+ !contains(QT_CONFIG, no-jpeg): DEPLOYMENT_PLUGIN += qjpeg
+}
diff --git a/tests/auto/qmediaimageviewer/tst_qmediaimageviewer.cpp b/tests/auto/qmediaimageviewer/tst_qmediaimageviewer.cpp
new file mode 100644
index 000000000..2bd56cf39
--- /dev/null
+++ b/tests/auto/qmediaimageviewer/tst_qmediaimageviewer.cpp
@@ -0,0 +1,1036 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include <qmobilityglobal.h>
+#include <QtTest/QtTest>
+
+#include <QtCore/qdir.h>
+
+#include <qgraphicsvideoitem.h>
+#include <qmediaimageviewer.h>
+#include <private/qmediaimageviewerservice_p.h>
+#include <qmediaplaylist.h>
+#include <qmediaservice.h>
+#include <qvideorenderercontrol.h>
+#include <qvideowidget.h>
+#include <qvideowidgetcontrol.h>
+
+#include <QtCore/qfile.h>
+#include <QtNetwork/qnetworkaccessmanager.h>
+#include <QtNetwork/qnetworkreply.h>
+
+#include <qabstractvideosurface.h>
+#include <qvideosurfaceformat.h>
+
+QT_USE_NAMESPACE
+class QtTestNetworkAccessManager;
+
+class tst_QMediaImageViewer : public QObject
+{
+ Q_OBJECT
+private slots:
+ void initTestCase();
+
+ void isValid();
+ void timeout();
+ void setMedia_data();
+ void setMedia();
+ void setConsecutiveMedia();
+ void setInvalidMedia();
+ void playlist();
+ void multiplePlaylists();
+ void invalidPlaylist();
+ void elapsedTime();
+ void rendererControl();
+ void setVideoOutput();
+ void debugEnums();
+
+public:
+ tst_QMediaImageViewer() : m_network(0) {}
+
+private:
+ QUrl imageUrl(const char *fileName) const {
+ return QUrl(QLatin1String("qrc:///images/") + QLatin1String(fileName)); }
+ QString imageFileName(const char *fileName) {
+ return QLatin1String(":/images/") + QLatin1String(fileName); }
+
+ QtTestNetworkAccessManager *m_network;
+ QString m_fileProtocol;
+};
+
+class QtTestVideoSurface : public QAbstractVideoSurface
+{
+public:
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const {
+ QList<QVideoFrame::PixelFormat> formats;
+ if (handleType == QAbstractVideoBuffer::NoHandle) {
+ formats << QVideoFrame::Format_RGB32;
+ }
+ return formats;
+ }
+
+ QVideoFrame frame() const { return m_frame; }
+
+ bool present(const QVideoFrame &frame) { m_frame = frame; return true; }
+
+private:
+ QVideoFrame m_frame;
+};
+
+class QtTestNetworkReply : public QNetworkReply
+{
+public:
+ QtTestNetworkReply(
+ const QNetworkRequest &request,
+ const QByteArray &mimeType,
+ QObject *parent)
+ : QNetworkReply(parent)
+ {
+ setRequest(request);
+ setOperation(QNetworkAccessManager::HeadOperation);
+ setRawHeader("content-type", mimeType);
+
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ }
+
+ QtTestNetworkReply(
+ const QNetworkRequest &request,
+ const QByteArray &mimeType,
+ const QString &fileName,
+ QObject *parent)
+ : QNetworkReply(parent)
+ , m_file(fileName)
+ {
+ setRequest(request);
+ setOperation(QNetworkAccessManager::GetOperation);
+ setRawHeader("content-type", mimeType);
+
+ if (m_file.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) {
+ setOpenMode(QIODevice::ReadOnly);
+ }
+
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ }
+
+ void abort() { m_file.close(); }
+
+ bool atEnd () const { return m_file.atEnd(); }
+ qint64 bytesAvailable() const { return m_file.bytesAvailable() + QIODevice::bytesAvailable(); }
+ void close() { m_file.close(); setOpenMode(QIODevice::NotOpen); }
+ bool isSequential() const { return true; }
+ bool open(OpenMode) { return false; }
+ qint64 pos() const { return 0; }
+ bool seek(qint64) { return false; }
+ qint64 size() const { return m_file.size(); }
+ qint64 readData(char * data, qint64 maxSize) { return m_file.read(data, maxSize); }
+ qint64 writeData(const char *, qint64) { return -1; }
+
+protected:
+ void customEvent(QEvent *event)
+ {
+ if (event->type() == QEvent::User) {
+ event->accept();
+ emit finished();
+ }
+ }
+
+private:
+ QFile m_file;
+};
+
+class QtTestNetworkAccessManager : public QNetworkAccessManager
+{
+public:
+ QtTestNetworkAccessManager(QObject *parent = 0)
+ : QNetworkAccessManager(parent)
+ {
+ }
+
+ void appendDocument(const QUrl &url, const QByteArray &mimeType, const QString &fileName)
+ {
+ m_documents.append(Document(url, mimeType, fileName));
+ }
+
+protected:
+ QNetworkReply *createRequest(
+ Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0)
+ {
+ foreach (const Document &document, m_documents) {
+ if (document.url == request.url()) {
+ if (op == GetOperation) {
+ return new QtTestNetworkReply(
+ request, document.mimeType, document.fileName, this);
+ } else if (op == HeadOperation) {
+ return new QtTestNetworkReply(request, document.mimeType, this);
+ }
+ }
+ }
+ return QNetworkAccessManager::createRequest(op, request, outgoingData);
+ }
+
+private:
+ struct Document
+ {
+ Document(const QUrl url, const QByteArray mimeType, const QString &fileName)
+ : url(url), mimeType(mimeType), fileName(fileName)
+ {
+ }
+
+ QUrl url;
+ QByteArray mimeType;
+ QString fileName;
+ };
+
+ QList<Document> m_documents;
+};
+
+void tst_QMediaImageViewer::initTestCase()
+{
+ qRegisterMetaType<QMediaImageViewer::State>();
+ qRegisterMetaType<QMediaImageViewer::MediaStatus>();
+
+ m_network = new QtTestNetworkAccessManager(this);
+
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://image/png?id=1")),
+ "image/png",
+ imageFileName("image.png"));
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://image/png?id=2")),
+ QByteArray(),
+ imageFileName("image.png"));
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://image/invalid?id=1")),
+ "image/png",
+ imageFileName("invalid.png"));
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://image/invalid?id=2")),
+ QByteArray(),
+ imageFileName("invalid.png"));
+#ifdef QTEST_HAVE_JPEG
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://image/jpeg?id=1")),
+ "image/jpeg",
+ imageFileName("image.jpg"));
+#endif
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://music/songs/mp3?id=1")),
+ "audio/mpeg",
+ QString());
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://music/covers/small?id=1")),
+ "image/png",
+ imageFileName("coverart.png"));
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://music/covers/large?id=1")),
+ "image/png",
+ imageFileName("coverart.png"));
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://video/movies/mp4?id=1")),
+ "video/mp4",
+ QString());
+ m_network->appendDocument(
+ QUrl(QLatin1String("test://video/posters/png?id=1")),
+ "image/png",
+ imageFileName("poster.png"));
+}
+
+void tst_QMediaImageViewer::isValid()
+{
+ QMediaImageViewer viewer;
+
+ QVERIFY(viewer.service() != 0);
+}
+
+void tst_QMediaImageViewer::timeout()
+{
+ QMediaImageViewer viewer;
+
+ QCOMPARE(viewer.timeout(), 3000);
+
+ viewer.setTimeout(0);
+ QCOMPARE(viewer.timeout(), 0);
+
+ viewer.setTimeout(45);
+ QCOMPARE(viewer.timeout(), 45);
+
+ viewer.setTimeout(-3000);
+ QCOMPARE(viewer.timeout(), 0);
+}
+
+void tst_QMediaImageViewer::setMedia_data()
+{
+ QTest::addColumn<QMediaContent>("media");
+
+ {
+ QMediaContent media(imageUrl("image.png"));
+
+ QTest::newRow("file: png image")
+ << media;
+ } {
+ QMediaContent media(QUrl(QLatin1String("test://image/png?id=1")));
+
+ QTest::newRow("network: png image")
+ << media;
+ } {
+ QMediaContent media(QMediaResource(
+ QUrl(QLatin1String("test://image/png?id=1")), QLatin1String("image/png")));
+
+ QTest::newRow("network: png image, explicit mime type")
+ << media;
+ } {
+ QMediaContent media(QUrl(QLatin1String("test://image/png?id=2")));
+
+ QTest::newRow("network: png image, no mime type")
+ << media;
+#ifdef QTEST_HAVE_JPEG
+ } {
+ QMediaContent media(imageUrl("image.jpg"));
+
+ QTest::newRow("file: jpg image")
+ << media;
+ } {
+ QMediaContent media(QUrl(QLatin1String("test://image/jpeg?id=1")));
+
+ QTest::newRow("network: jpg image")
+ << media;
+#endif
+ }
+}
+
+void tst_QMediaImageViewer::setMedia()
+{
+ QFETCH(QMediaContent, media);
+
+ QMediaImageViewer viewer;
+
+ QMediaImageViewerService *service = qobject_cast<QMediaImageViewerService *>(viewer.service());
+ service->setNetworkManager(m_network);
+
+ connect(&viewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ viewer.setMedia(media);
+ QCOMPARE(viewer.media(), media);
+
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+}
+
+void tst_QMediaImageViewer::setConsecutiveMedia()
+{
+ QMediaContent fileMedia1(imageUrl("image.png"));
+ QMediaContent fileMedia2(imageUrl("coverart.png"));
+ QMediaContent networkMedia1(QUrl(QLatin1String("test://image/png?id=1")));
+ QMediaContent networkMedia2(QUrl(QLatin1String("test://image/png?id=2")));
+
+ QMediaImageViewer viewer;
+
+ connect(&viewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ viewer.setMedia(fileMedia1);
+ viewer.setMedia(fileMedia2);
+
+ QCOMPARE(viewer.media(), fileMedia2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.media(), fileMedia2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+
+ QMediaImageViewerService *service = qobject_cast<QMediaImageViewerService *>(viewer.service());
+ service->setNetworkManager(m_network);
+
+ viewer.setMedia(networkMedia1);
+ viewer.setMedia(networkMedia2);
+
+ QCOMPARE(viewer.media(), networkMedia2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.media(), networkMedia2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+
+ viewer.setMedia(fileMedia1);
+ viewer.setMedia(networkMedia2);
+
+ QCOMPARE(viewer.media(), networkMedia2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.media(), networkMedia2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+
+ viewer.setMedia(networkMedia1);
+ viewer.setMedia(fileMedia2);
+
+ QCOMPARE(viewer.media(), fileMedia2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.media(), fileMedia2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+}
+
+void tst_QMediaImageViewer::setInvalidMedia()
+{
+ QMediaImageViewer viewer;
+
+ QMediaImageViewerService *service = qobject_cast<QMediaImageViewerService *>(viewer.service());
+ service->setNetworkManager(m_network);
+
+ connect(&viewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ {
+ QMediaContent media(imageUrl("invalid.png"));
+
+ viewer.setMedia(media);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::InvalidMedia);
+ QCOMPARE(viewer.media(), media);
+ } {
+ QMediaContent media(imageUrl("deleted.png"));
+
+ viewer.setMedia(media);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::InvalidMedia);
+ QCOMPARE(viewer.media(), media);
+ } {
+ QMediaResource invalidResource(imageUrl("invalid.png"));
+ QMediaResource deletedResource(imageUrl("deleted.png"));
+ QMediaContent media(QMediaResourceList() << invalidResource << deletedResource);
+
+ viewer.setMedia(media);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::InvalidMedia);
+ QCOMPARE(viewer.media(), media);
+ } {
+ QMediaResource resource(imageUrl("image.png"), QLatin1String("audio/mpeg"));
+ QMediaContent media(resource);
+
+ viewer.setMedia(media);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::InvalidMedia);
+ QCOMPARE(viewer.media(), media);
+ } {
+ QMediaResource audioResource(imageUrl("image.png"), QLatin1String("audio/mpeg"));
+ QMediaResource invalidResource(imageUrl("invalid.png"));
+ QMediaContent media(QMediaResourceList() << audioResource << invalidResource);
+
+ viewer.setMedia(media);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::InvalidMedia);
+ QCOMPARE(viewer.media(), media);
+ } {
+ QMediaContent media(QUrl(QLatin1String("test://image/invalid?id=1")));
+
+ viewer.setMedia(media);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::InvalidMedia);
+ QCOMPARE(viewer.media(), media);
+ } {
+ QMediaContent media(QUrl(QLatin1String("test://image/invalid?id=2")));
+
+ viewer.setMedia(media);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::InvalidMedia);
+ QCOMPARE(viewer.media(), media);
+ } {
+ QMediaContent media(QUrl(QLatin1String("test://image/invalid?id=3")));
+
+ viewer.setMedia(media);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::InvalidMedia);
+ QCOMPARE(viewer.media(), media);
+ }
+}
+
+void tst_QMediaImageViewer::playlist()
+{
+ QMediaContent imageMedia(imageUrl("image.png"));
+ QMediaContent posterMedia(imageUrl("poster.png"));
+ QMediaContent coverArtMedia(imageUrl("coverart.png"));
+
+ QMediaImageViewer viewer;
+ viewer.setTimeout(250);
+
+ connect(&viewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ QSignalSpy stateSpy(&viewer, SIGNAL(stateChanged(QMediaImageViewer::State)));
+
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+
+ // No playlist so can't exit stopped state.
+ viewer.play();
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+ viewer.pause();
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ QMediaPlaylist playlist;
+ viewer.setPlaylist(&playlist);
+
+ // Empty playlist so can't exit stopped state.
+ viewer.play();
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+ viewer.pause();
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ playlist.addMedia(imageMedia);
+ playlist.addMedia(posterMedia);
+ playlist.addMedia(coverArtMedia);
+
+ // Play progresses immediately to the first image and starts loading.
+ viewer.play();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+ QCOMPARE(stateSpy.count(), 1);
+ QCOMPARE(qvariant_cast<QMediaImageViewer::State>(stateSpy.last().value(0)),
+ QMediaImageViewer::PlayingState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+ QCOMPARE(playlist.currentIndex(), 0);
+ QCOMPARE(viewer.media(), imageMedia);
+
+ // Image is loaded asynchronously.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+ QCOMPARE(playlist.currentIndex(), 0);
+
+ // Time out causes progression to second image, which starts loading.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+ QCOMPARE(playlist.currentIndex(), 1);
+ QCOMPARE(viewer.media(), posterMedia);
+
+ // Image is loaded asynchronously.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+ QCOMPARE(playlist.currentIndex(), 1);
+
+ // Pausing stops progression at current image.
+ viewer.pause();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PausedState);
+ QCOMPARE(stateSpy.count(), 2);
+ QCOMPARE(qvariant_cast<QMediaImageViewer::State>(stateSpy.last().value(0)),
+ QMediaImageViewer::PausedState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+ QCOMPARE(playlist.currentIndex(), 1);
+
+ // No time out.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::PausedState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+ QCOMPARE(playlist.currentIndex(), 1);
+
+ // Resuming playback does not immediately progress to the next item
+ viewer.play();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+ QCOMPARE(playlist.currentIndex(), 1);
+
+ // Time out causes progression to next image, which starts loading.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+ QCOMPARE(playlist.currentIndex(), 2);
+ QCOMPARE(viewer.media(), coverArtMedia);
+
+ // Image is loaded asynchronously.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+ QCOMPARE(playlist.currentIndex(), 2);
+
+ // Time out causes progression to end of list
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(stateSpy.count(), 4);
+ QCOMPARE(qvariant_cast<QMediaImageViewer::State>(stateSpy.last().value(0)),
+ QMediaImageViewer::StoppedState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::NoMedia);
+ QCOMPARE(playlist.currentIndex(), -1);
+ QCOMPARE(viewer.media(), QMediaContent());
+
+ // Stopped, no time out.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::NoMedia);
+ QCOMPARE(playlist.currentIndex(), -1);
+
+ // Play progresses immediately to the first image and starts loading.
+ viewer.play();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+ QCOMPARE(stateSpy.count(), 5);
+ QCOMPARE(qvariant_cast<QMediaImageViewer::State>(stateSpy.last().value(0)),
+ QMediaImageViewer::PlayingState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+ QCOMPARE(playlist.currentIndex(), 0);
+ QCOMPARE(viewer.media(), imageMedia);
+
+ // Image is loaded asynchronously.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+ QCOMPARE(playlist.currentIndex(), 0);
+
+ // Stop ends progress, but retains current index.
+ viewer.stop();
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(stateSpy.count(), 6);
+ QCOMPARE(qvariant_cast<QMediaImageViewer::State>(stateSpy.last().value(0)),
+ QMediaImageViewer::StoppedState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+ QCOMPARE(playlist.currentIndex(), 0);
+ QCOMPARE(viewer.media(), imageMedia);
+
+ // Stoppped, No time out.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(playlist.currentIndex(), 0);
+ QCOMPARE(viewer.media(), imageMedia);
+
+ // Stop when already stopped doesn't emit additional signals.
+ viewer.stop();
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(stateSpy.count(), 6);
+
+ viewer.play();
+ QCOMPARE(stateSpy.count(), 7);
+
+ // Play when already playing doesn't emit additional signals.
+ viewer.play();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+ QCOMPARE(stateSpy.count(), 7);
+
+ playlist.next();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ // Pausing while loading, doesn't stop loading.
+ viewer.pause();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PausedState);
+ QCOMPARE(stateSpy.count(), 8);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::PausedState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadedMedia);
+
+ // Pause while paused doesn't emit additional signals.
+ viewer.pause();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PausedState);
+ QCOMPARE(stateSpy.count(), 8);
+
+ // Calling setMedia stops the playlist.
+ viewer.setMedia(imageMedia);
+ QCOMPARE(viewer.media(), imageMedia);
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(stateSpy.count(), 9);
+ QCOMPARE(qvariant_cast<QMediaImageViewer::State>(stateSpy.last().value(0)),
+ QMediaImageViewer::StoppedState);
+
+}
+
+void tst_QMediaImageViewer::multiplePlaylists()
+{
+ QMediaContent imageMedia(imageUrl("image.png"));
+ QMediaContent posterMedia(imageUrl("poster.png"));
+ QMediaContent coverArtMedia(imageUrl("coverart.png"));
+
+ QMediaImageViewer viewer;
+
+ QMediaPlaylist *playlist1 = new QMediaPlaylist;
+ viewer.setPlaylist(playlist1);
+ playlist1->addMedia(imageMedia);
+ playlist1->addMedia(posterMedia);
+
+ playlist1->setCurrentIndex(0);
+ QCOMPARE(viewer.media(), imageMedia);
+
+ QMediaPlaylist *playlist2 = new QMediaPlaylist;
+
+ viewer.setPlaylist(playlist2);
+ playlist2->addMedia(coverArtMedia);
+
+ QVERIFY(viewer.media().isNull());
+
+ playlist2->setCurrentIndex(0);
+ QCOMPARE(viewer.media(), coverArtMedia);
+
+ delete playlist2;
+ QVERIFY(viewer.media().isNull());
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+
+ viewer.setPlaylist(playlist1);
+ playlist1->setCurrentIndex(0);
+ QCOMPARE(viewer.media(), imageMedia);
+
+ viewer.play();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+
+ delete playlist1;
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+}
+
+
+void tst_QMediaImageViewer::invalidPlaylist()
+{
+ QMediaContent imageMedia(imageUrl("image.png"));
+ QMediaContent invalidMedia(imageUrl("invalid.png"));
+
+ QMediaImageViewer viewer;
+ viewer.setTimeout(250);
+
+ connect(&viewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ QSignalSpy stateSpy(&viewer, SIGNAL(stateChanged(QMediaImageViewer::State)));
+ QSignalSpy statusSpy(&viewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)));
+
+ QMediaPlaylist playlist;
+ viewer.setPlaylist(&playlist);
+ playlist.addMedia(invalidMedia);
+ playlist.addMedia(imageMedia);
+ playlist.addMedia(invalidMedia);
+
+ // Test play initially tries to load the first invalid image.
+ viewer.play();
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+ QCOMPARE(viewer.media(), invalidMedia);
+ QCOMPARE(playlist.currentIndex(), 0);
+ QCOMPARE(statusSpy.count(), 1);
+ QCOMPARE(qvariant_cast<QMediaImageViewer::MediaStatus>(statusSpy.value(0).value(0)),
+ QMediaImageViewer::LoadingMedia);
+
+ // Test status is changed to InvalidMedia, and loading of the next image is started immediately.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::LoadingMedia);
+ QCOMPARE(viewer.media(), imageMedia);
+ QCOMPARE(playlist.currentIndex(), 1);
+ QCOMPARE(statusSpy.count(), 3);
+ QCOMPARE(qvariant_cast<QMediaImageViewer::MediaStatus>(statusSpy.value(1).value(0)),
+ QMediaImageViewer::InvalidMedia);
+ QCOMPARE(qvariant_cast<QMediaImageViewer::MediaStatus>(statusSpy.value(2).value(0)),
+ QMediaImageViewer::LoadingMedia);
+
+ // Test if the last image is invalid, the image viewer is stopped.
+ playlist.next();
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::NoMedia);
+ QCOMPARE(playlist.currentIndex(), -1);
+ QCOMPARE(stateSpy.count(), 2);
+
+ playlist.setCurrentIndex(2);
+ QTestEventLoop::instance().enterLoop(2);
+
+ // Test play immediately moves to the next item if the current one is invalid, and no state
+ // change signals are emitted if the viewer never effectively moves from the StoppedState.
+ viewer.play();
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+ QCOMPARE(viewer.mediaStatus(), QMediaImageViewer::NoMedia);
+ QCOMPARE(playlist.currentIndex(), -1);
+ QCOMPARE(stateSpy.count(), 2);
+}
+
+void tst_QMediaImageViewer::elapsedTime()
+{
+ QMediaContent imageMedia(imageUrl("image.png"));
+
+ QMediaImageViewer viewer;
+ viewer.setTimeout(250);
+ viewer.setNotifyInterval(150);
+
+ QSignalSpy spy(&viewer, SIGNAL(elapsedTimeChanged(int)));
+
+ connect(&viewer, SIGNAL(elapsedTimeChanged(int)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+
+ QMediaPlaylist playlist;
+ viewer.setPlaylist(&playlist);
+ playlist.addMedia(imageMedia);
+
+ QCOMPARE(viewer.elapsedTime(), 0);
+
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(spy.count(), 0);
+
+ viewer.play();
+ QCOMPARE(viewer.elapsedTime(), 0);
+
+ // Emits an initial elapsed time at 0 milliseconds signal when the image is loaded.
+ QTestEventLoop::instance().enterLoop(1);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.last().value(0).toInt(), 0);
+
+ // Emits a scheduled signal after the notify interval is up. The exact time will be a little
+ // fuzzy.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(spy.count(), 2);
+ QVERIFY(spy.last().value(0).toInt() != 0);
+
+ // Pausing will emit a signal with the elapsed time when paused.
+ viewer.pause();
+ QCOMPARE(spy.count(), 3);
+ QCOMPARE(viewer.elapsedTime(), spy.last().value(0).toInt());
+
+ // No elapsed time signals will be emitted while paused.
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(spy.count(), 3);
+
+ // Stopping a paused viewer resets the elapsed time to 0 with signals emitted.
+ viewer.stop();
+ QCOMPARE(viewer.elapsedTime(), 0);
+ QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.last().value(0).toInt(), 0);
+
+ disconnect(&viewer, SIGNAL(elapsedTimeChanged(int)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ connect(&viewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ // Play until end.
+ viewer.play();
+ QTestEventLoop::instance().enterLoop(2);
+
+ // Verify at least two more signals are emitted.
+ // The second to last at the instant the timeout expired, and the last as it's reset when the
+ // current media is cleared.
+ QVERIFY(spy.count() >= 5);
+ QCOMPARE(spy.value(spy.count() - 2).value(0).toInt(), 250);
+ QCOMPARE(spy.value(spy.count() - 1).value(0).toInt(), 0);
+
+ viewer.play();
+ QTestEventLoop::instance().enterLoop(2);
+
+ // Test extending the timeout applies to an already loaded image.
+ viewer.setTimeout(10000);
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::PlayingState);
+
+ // Test reducing the timeout applies to an already loaded image.
+ viewer.setTimeout(1000);
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(viewer.state(), QMediaImageViewer::StoppedState);
+
+}
+
+void tst_QMediaImageViewer::rendererControl()
+{
+ QtTestVideoSurface surfaceA;
+ QtTestVideoSurface surfaceB;
+ QAbstractVideoSurface *nullSurface = 0;
+
+ QMediaImageViewer viewer;
+
+ QMediaService *service = viewer.service();
+ if (service == 0)
+ QSKIP("Image viewer object has no service.", SkipSingle);
+
+ QMediaControl *mediaControl = service->requestControl(QVideoRendererControl_iid);
+ QVERIFY(mediaControl != 0);
+
+ QVideoRendererControl *rendererControl = qobject_cast<QVideoRendererControl *>(mediaControl);
+ QVERIFY(rendererControl != 0);
+
+ rendererControl->setSurface(&surfaceA);
+ QCOMPARE(rendererControl->surface(), (QAbstractVideoSurface *)&surfaceA);
+
+ // Load an image so the viewer has some dimensions to work with.
+ viewer.setMedia(QMediaContent(imageUrl("image.png")));
+
+ connect(&viewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+ QTestEventLoop::instance().enterLoop(2);
+
+ if (viewer.mediaStatus() != QMediaImageViewer::LoadedMedia)
+ QSKIP("failed to load test image", SkipSingle);
+
+ QCOMPARE(surfaceA.isActive(), true);
+
+ {
+ QVideoSurfaceFormat format = surfaceA.surfaceFormat();
+ QCOMPARE(format.handleType(), QAbstractVideoBuffer::NoHandle);
+ QCOMPARE(format.pixelFormat(), QVideoFrame::Format_RGB32);
+ QCOMPARE(format.frameSize(), QSize(75, 50));
+
+ QVideoFrame frame = surfaceA.frame();
+ QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle);
+ QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_RGB32);
+ QCOMPARE(frame.size(), QSize(75, 50));
+ }
+ // Test clearing the output stops the video surface.
+ service->releaseControl(rendererControl);
+ QCOMPARE(surfaceA.isActive(), false);
+
+ // Test reseting the output restarts it.
+ mediaControl = service->requestControl(QVideoRendererControl_iid);
+ QVERIFY(mediaControl != 0);
+
+ rendererControl = qobject_cast<QVideoRendererControl *>(mediaControl);
+ rendererControl->setSurface(&surfaceA);
+ QVERIFY(rendererControl != 0);
+ {
+ QVideoSurfaceFormat format = surfaceA.surfaceFormat();
+ QCOMPARE(format.handleType(), QAbstractVideoBuffer::NoHandle);
+ QCOMPARE(format.pixelFormat(), QVideoFrame::Format_RGB32);
+ QCOMPARE(format.frameSize(), QSize(75, 50));
+
+ QVideoFrame frame = surfaceA.frame();
+ QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle);
+ QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_RGB32);
+ QCOMPARE(frame.size(), QSize(75, 50));
+ }
+
+ // Test changing the surface while viewing an image stops the old surface and starts
+ // the new one and presents the image.
+ rendererControl->setSurface(&surfaceB);
+ QCOMPARE(rendererControl->surface(), (QAbstractVideoSurface*)&surfaceB);
+
+ QCOMPARE(surfaceA.isActive(), false);
+ QCOMPARE(surfaceB.isActive(), true);
+
+ QVideoSurfaceFormat format = surfaceB.surfaceFormat();
+ QCOMPARE(format.handleType(), QAbstractVideoBuffer::NoHandle);
+ QCOMPARE(format.pixelFormat(), QVideoFrame::Format_RGB32);
+ QCOMPARE(format.frameSize(), QSize(75, 50));
+
+ QVideoFrame frame = surfaceB.frame();
+ QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle);
+ QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_RGB32);
+ QCOMPARE(frame.size(), QSize(75, 50));
+
+ // Test setting null media stops the surface.
+ viewer.setMedia(QMediaContent());
+ QCOMPARE(surfaceB.isActive(), false);
+
+ // Test the renderer control accepts a null surface.
+ rendererControl->setSurface(0);
+ QCOMPARE(rendererControl->surface(), nullSurface);
+}
+
+void tst_QMediaImageViewer::setVideoOutput()
+{
+ QMediaImageViewer imageViewer;
+ imageViewer.setMedia(QMediaContent(imageUrl("image.png")));
+
+ connect(&imageViewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+ QTestEventLoop::instance().enterLoop(2);
+
+ if (imageViewer.mediaStatus() != QMediaImageViewer::LoadedMedia)
+ QSKIP("failed to load test image", SkipSingle);
+
+ QVideoWidget widget;
+ QGraphicsVideoItem item;
+ QtTestVideoSurface surface;
+
+ imageViewer.setVideoOutput(&widget);
+ QVERIFY(widget.mediaObject() == &imageViewer);
+
+ imageViewer.setVideoOutput(&item);
+ QVERIFY(widget.mediaObject() == 0);
+ QVERIFY(item.mediaObject() == &imageViewer);
+
+ imageViewer.setVideoOutput(reinterpret_cast<QVideoWidget *>(0));
+ QVERIFY(item.mediaObject() == 0);
+
+ imageViewer.setVideoOutput(&widget);
+ QVERIFY(widget.mediaObject() == &imageViewer);
+
+ imageViewer.setVideoOutput(reinterpret_cast<QGraphicsVideoItem *>(0));
+ QVERIFY(widget.mediaObject() == 0);
+
+ imageViewer.setVideoOutput(&surface);
+ QVERIFY(surface.isActive());
+
+ imageViewer.setVideoOutput(reinterpret_cast<QAbstractVideoSurface *>(0));
+ QVERIFY(!surface.isActive());
+
+ imageViewer.setVideoOutput(&surface);
+ QVERIFY(surface.isActive());
+
+ imageViewer.setVideoOutput(&widget);
+ QVERIFY(!surface.isActive());
+ QVERIFY(widget.mediaObject() == &imageViewer);
+
+ imageViewer.setVideoOutput(&surface);
+ QVERIFY(surface.isActive());
+ QVERIFY(widget.mediaObject() == 0);
+}
+
+void tst_QMediaImageViewer::debugEnums()
+{
+ QTest::ignoreMessage(QtDebugMsg, "QMediaImageViewer::PlayingState ");
+ qDebug() << QMediaImageViewer::PlayingState;
+ QTest::ignoreMessage(QtDebugMsg, "QMediaImageViewer::NoMedia ");
+ qDebug() << QMediaImageViewer::NoMedia;
+}
+
+QTEST_MAIN(tst_QMediaImageViewer)
+
+#include "tst_qmediaimageviewer.moc"
diff --git a/tests/auto/qmediaobject/main.cpp b/tests/auto/qmediaobject/main.cpp
new file mode 100644
index 000000000..4dc763f11
--- /dev/null
+++ b/tests/auto/qmediaobject/main.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCore/qcoreapplication.h>
+#include <QtTest/QtTest>
+
+#include "tst_qmediaobject.h"
+#ifdef Q_OS_SYMBIAN
+#include "tst_qmediaobject_xa.h"
+#include "tst_qmediaobject_mmf.h"
+#endif
+
+int main(int argc, char**argv)
+{
+ QApplication app(argc,argv);
+ int ret;
+ tst_QMediaObject test_api;
+ ret = QTest::qExec(&test_api, argc, argv);
+#ifdef Q_OS_SYMBIAN
+ char *new_argv[3];
+ QString str = "C:\\data\\" + QFileInfo(QCoreApplication::applicationFilePath()).baseName() + "_xa.log";
+ QByteArray bytes = str.toAscii();
+ char arg1[] = "-o";
+ new_argv[0] = argv[0];
+ new_argv[1] = arg1;
+ new_argv[2] = bytes.data();
+ tst_QMetadata_xa test_xa;
+ ret = QTest::qExec(&test_xa, 3, new_argv);
+ char *new_argv1[3];
+ QString str1 = "C:\\data\\" + QFileInfo(QCoreApplication::applicationFilePath()).baseName() + "_s60.log";
+ QByteArray bytes1 = str1.toAscii();
+ char arg2[] = "-o";
+ new_argv1[0] = argv[0];
+ new_argv1[1] = arg2;
+ new_argv1[2] = bytes1.data();
+ tst_QMediaObject_mmf test_mmf;
+ ret = QTest::qExec(&test_mmf, 3, new_argv1);
+#endif
+ return ret;
+}
diff --git a/tests/auto/qmediaobject/qmediaobject.pro b/tests/auto/qmediaobject/qmediaobject.pro
new file mode 100644
index 000000000..756603ad7
--- /dev/null
+++ b/tests/auto/qmediaobject/qmediaobject.pro
@@ -0,0 +1,27 @@
+load(qttest_p4)
+
+QT += multimediakit-private
+
+# TARGET = tst_qmediaobject
+# CONFIG += testcase
+
+symbian {
+ HEADERS += tst_qmediaobject_xa.h
+ SOURCES += tst_qmediaobject_xa.cpp
+ TARGET.CAPABILITY = ALL -TCB
+
+ testFiles.sources = testfiles/*
+ testFiles.path = /Data/testfiles
+ DEPLOYMENT += testFiles
+ HEADERS += tst_qmediaobject_mmf.h
+ SOURCES += tst_qmediaobject_mmf.cpp
+ TARGET.CAPABILITY = ALL -TCB
+
+ testFiles.sources = testfiles/*
+ testFiles.path = /Data/testfiles
+ DEPLOYMENT += testFiles
+}
+
+HEADERS+= tst_qmediaobject.h
+SOURCES += main.cpp tst_qmediaobject.cpp
+
diff --git a/tests/auto/qmediaobject/tst_qmediaobject.cpp b/tests/auto/qmediaobject/tst_qmediaobject.cpp
new file mode 100644
index 000000000..b286c4ed9
--- /dev/null
+++ b/tests/auto/qmediaobject/tst_qmediaobject.cpp
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include "tst_qmediaobject.h"
+
+QT_USE_NAMESPACE
+
+void tst_QMediaObject::propertyWatch()
+{
+ QtTestMediaObject object;
+ object.setNotifyInterval(0);
+
+ QEventLoop loop;
+ connect(&object, SIGNAL(aChanged(int)), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ connect(&object, SIGNAL(bChanged(int)), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ connect(&object, SIGNAL(cChanged(int)), &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ QSignalSpy aSpy(&object, SIGNAL(aChanged(int)));
+ QSignalSpy bSpy(&object, SIGNAL(bChanged(int)));
+ QSignalSpy cSpy(&object, SIGNAL(cChanged(int)));
+
+ QTestEventLoop::instance().enterLoop(1);
+
+ QCOMPARE(aSpy.count(), 0);
+ QCOMPARE(bSpy.count(), 0);
+ QCOMPARE(cSpy.count(), 0);
+
+ int aCount = 0;
+ int bCount = 0;
+ int cCount = 0;
+
+ object.addPropertyWatch("a");
+
+ QTestEventLoop::instance().enterLoop(1);
+
+ QVERIFY(aSpy.count() > aCount);
+ QCOMPARE(bSpy.count(), 0);
+ QCOMPARE(cSpy.count(), 0);
+ QCOMPARE(aSpy.last().value(0).toInt(), 0);
+
+ aCount = aSpy.count();
+
+ object.setA(54);
+ object.setB(342);
+ object.setC(233);
+
+ QTestEventLoop::instance().enterLoop(1);
+
+ QVERIFY(aSpy.count() > aCount);
+ QCOMPARE(bSpy.count(), 0);
+ QCOMPARE(cSpy.count(), 0);
+ QCOMPARE(aSpy.last().value(0).toInt(), 54);
+
+ aCount = aSpy.count();
+
+ object.addPropertyWatch("b");
+ object.addPropertyWatch("d");
+ object.removePropertyWatch("e");
+ object.setA(43);
+ object.setB(235);
+ object.setC(90);
+
+ QTestEventLoop::instance().enterLoop(1);
+
+ QVERIFY(aSpy.count() > aCount);
+ QVERIFY(bSpy.count() > bCount);
+ QCOMPARE(cSpy.count(), 0);
+ QCOMPARE(aSpy.last().value(0).toInt(), 43);
+ QCOMPARE(bSpy.last().value(0).toInt(), 235);
+
+ aCount = aSpy.count();
+ bCount = bSpy.count();
+
+ object.removePropertyWatch("a");
+ object.addPropertyWatch("c");
+ object.addPropertyWatch("e");
+
+ QTestEventLoop::instance().enterLoop(1);
+
+ QCOMPARE(aSpy.count(), aCount);
+ QVERIFY(bSpy.count() > bCount);
+ QVERIFY(cSpy.count() > cCount);
+ QCOMPARE(bSpy.last().value(0).toInt(), 235);
+ QCOMPARE(cSpy.last().value(0).toInt(), 90);
+
+ bCount = bSpy.count();
+ cCount = cSpy.count();
+
+ object.setA(435);
+ object.setC(9845);
+
+ QTestEventLoop::instance().enterLoop(1);
+
+ QCOMPARE(aSpy.count(), aCount);
+ QVERIFY(bSpy.count() > bCount);
+ QVERIFY(cSpy.count() > cCount);
+ QCOMPARE(bSpy.last().value(0).toInt(), 235);
+ QCOMPARE(cSpy.last().value(0).toInt(), 9845);
+
+ bCount = bSpy.count();
+ cCount = cSpy.count();
+
+ object.setA(8432);
+ object.setB(324);
+ object.setC(443);
+ object.removePropertyWatch("c");
+ object.removePropertyWatch("d");
+
+ QTestEventLoop::instance().enterLoop(1);
+
+ QCOMPARE(aSpy.count(), aCount);
+ QVERIFY(bSpy.count() > bCount);
+ QCOMPARE(cSpy.count(), cCount);
+ QCOMPARE(bSpy.last().value(0).toInt(), 324);
+ QCOMPARE(cSpy.last().value(0).toInt(), 9845);
+
+ bCount = bSpy.count();
+
+ object.removePropertyWatch("b");
+
+ QTestEventLoop::instance().enterLoop(1);
+
+ QCOMPARE(aSpy.count(), aCount);
+ QCOMPARE(bSpy.count(), bCount);
+ QCOMPARE(cSpy.count(), cCount);
+}
+
+void tst_QMediaObject::setupNotifyTests()
+{
+ QTest::addColumn<int>("interval");
+ QTest::addColumn<int>("count");
+
+ QTest::newRow("single 750ms")
+ << 750
+ << 1;
+ QTest::newRow("single 600ms")
+ << 600
+ << 1;
+ QTest::newRow("x3 300ms")
+ << 300
+ << 3;
+ QTest::newRow("x5 180ms")
+ << 180
+ << 5;
+}
+
+void tst_QMediaObject::notifySignals_data()
+{
+ setupNotifyTests();
+}
+
+void tst_QMediaObject::notifySignals()
+{
+ QFETCH(int, interval);
+ QFETCH(int, count);
+
+ QtTestMediaObject object;
+ object.setNotifyInterval(interval);
+ object.addPropertyWatch("a");
+
+ QSignalSpy spy(&object, SIGNAL(aChanged(int)));
+
+ QTestEventLoop::instance().enterLoop(1);
+
+ QCOMPARE(spy.count(), count);
+}
+
+void tst_QMediaObject::notifyInterval_data()
+{
+ setupNotifyTests();
+}
+
+void tst_QMediaObject::notifyInterval()
+{
+ QFETCH(int, interval);
+
+ QtTestMediaObject object;
+ QSignalSpy spy(&object, SIGNAL(notifyIntervalChanged(int)));
+
+ object.setNotifyInterval(interval);
+ QCOMPARE(object.notifyInterval(), interval);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.last().value(0).toInt(), interval);
+
+ object.setNotifyInterval(interval);
+ QCOMPARE(object.notifyInterval(), interval);
+ QCOMPARE(spy.count(), 1);
+}
+
+void tst_QMediaObject::nullMetaDataControl()
+{
+ const QString titleKey(QLatin1String("Title"));
+ const QString title(QLatin1String("Host of Seraphim"));
+
+ QtTestMetaDataService service;
+ service.hasMetaData = false;
+
+ QtTestMediaObject object(&service);
+
+ QSignalSpy spy(&object, SIGNAL(metaDataChanged()));
+
+ QCOMPARE(object.isMetaDataAvailable(), false);
+
+ QCOMPARE(object.metaData(QtMultimediaKit::Title).toString(), QString());
+ QCOMPARE(object.extendedMetaData(titleKey).toString(), QString());
+ QCOMPARE(object.availableMetaData(), QList<QtMultimediaKit::MetaData>());
+ QCOMPARE(object.availableExtendedMetaData(), QStringList());
+ QCOMPARE(spy.count(), 0);
+}
+
+void tst_QMediaObject::isMetaDataAvailable()
+{
+ QtTestMetaDataService service;
+ service.metaData.setMetaDataAvailable(false);
+
+ QtTestMediaObject object(&service);
+ QCOMPARE(object.isMetaDataAvailable(), false);
+
+ QSignalSpy spy(&object, SIGNAL(metaDataAvailableChanged(bool)));
+ service.metaData.setMetaDataAvailable(true);
+
+ QCOMPARE(object.isMetaDataAvailable(), true);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toBool(), true);
+
+ service.metaData.setMetaDataAvailable(false);
+
+ QCOMPARE(object.isMetaDataAvailable(), false);
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.at(1).at(0).toBool(), false);
+}
+
+void tst_QMediaObject::metaDataChanged()
+{
+ QtTestMetaDataService service;
+ QtTestMediaObject object(&service);
+
+ QSignalSpy spy(&object, SIGNAL(metaDataChanged()));
+
+ service.metaData.metaDataChanged();
+ QCOMPARE(spy.count(), 1);
+
+ service.metaData.metaDataChanged();
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_QMediaObject::metaData_data()
+{
+ QTest::addColumn<QString>("artist");
+ QTest::addColumn<QString>("title");
+ QTest::addColumn<QString>("genre");
+
+ QTest::newRow("")
+ << QString::fromLatin1("Dead Can Dance")
+ << QString::fromLatin1("Host of Seraphim")
+ << QString::fromLatin1("Awesome");
+}
+
+void tst_QMediaObject::metaData()
+{
+ QFETCH(QString, artist);
+ QFETCH(QString, title);
+ QFETCH(QString, genre);
+
+ QtTestMetaDataService service;
+ service.metaData.populateMetaData();
+
+ QtTestMediaObject object(&service);
+ QVERIFY(object.availableMetaData().isEmpty());
+
+ service.metaData.m_data.insert(QtMultimediaKit::AlbumArtist, artist);
+ service.metaData.m_data.insert(QtMultimediaKit::Title, title);
+ service.metaData.m_data.insert(QtMultimediaKit::Genre, genre);
+
+ QCOMPARE(object.metaData(QtMultimediaKit::AlbumArtist).toString(), artist);
+ QCOMPARE(object.metaData(QtMultimediaKit::Title).toString(), title);
+
+ QList<QtMultimediaKit::MetaData> metaDataKeys = object.availableMetaData();
+ QCOMPARE(metaDataKeys.size(), 3);
+ QVERIFY(metaDataKeys.contains(QtMultimediaKit::AlbumArtist));
+ QVERIFY(metaDataKeys.contains(QtMultimediaKit::Title));
+ QVERIFY(metaDataKeys.contains(QtMultimediaKit::Genre));
+}
+
+void tst_QMediaObject::extendedMetaData()
+{
+ QFETCH(QString, artist);
+ QFETCH(QString, title);
+ QFETCH(QString, genre);
+
+ QtTestMetaDataService service;
+ QtTestMediaObject object(&service);
+ QVERIFY(object.availableExtendedMetaData().isEmpty());
+
+ service.metaData.m_extendedData.insert(QLatin1String("Artist"), artist);
+ service.metaData.m_extendedData.insert(QLatin1String("Title"), title);
+ service.metaData.m_extendedData.insert(QLatin1String("Genre"), genre);
+
+ QCOMPARE(object.extendedMetaData(QLatin1String("Artist")).toString(), artist);
+ QCOMPARE(object.extendedMetaData(QLatin1String("Title")).toString(), title);
+
+ QStringList extendedKeys = object.availableExtendedMetaData();
+ QCOMPARE(extendedKeys.size(), 3);
+ QVERIFY(extendedKeys.contains(QLatin1String("Artist")));
+ QVERIFY(extendedKeys.contains(QLatin1String("Title")));
+ QVERIFY(extendedKeys.contains(QLatin1String("Genre")));
+}
+
+void tst_QMediaObject::availability()
+{
+ QtTestMediaObject nullObject(0);
+ QCOMPARE(nullObject.isAvailable(), false);
+ QCOMPARE(nullObject.availabilityError(), QtMultimediaKit::ServiceMissingError);
+
+ QtTestMetaDataService service;
+ QtTestMediaObject object(&service);
+ QCOMPARE(object.isAvailable(), true);
+ QCOMPARE(object.availabilityError(), QtMultimediaKit::NoError);
+}
diff --git a/tests/auto/qmediaobject/tst_qmediaobject.h b/tests/auto/qmediaobject/tst_qmediaobject.h
new file mode 100644
index 000000000..3b46f752f
--- /dev/null
+++ b/tests/auto/qmediaobject/tst_qmediaobject.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef TST_QMEDIAOBJECT_H
+#define TST_QMEDIAOBJECT_H
+
+#include <QtTest/QtTest>
+
+#include <QtCore/qtimer.h>
+
+#include <qmediaobject.h>
+#include <qmediaservice.h>
+#include <qmetadatareadercontrol.h>
+
+//TESTED_COMPONENT=src/multimedia
+
+QT_USE_NAMESPACE
+class tst_QMediaObject : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void propertyWatch();
+ void notifySignals_data();
+ void notifySignals();
+ void notifyInterval_data();
+ void notifyInterval();
+
+ void nullMetaDataControl();
+ void isMetaDataAvailable();
+ void metaDataChanged();
+ void metaData_data();
+ void metaData();
+ void availability();
+ void extendedMetaData_data() { metaData_data(); }
+ void extendedMetaData();
+
+
+private:
+ void setupNotifyTests();
+};
+
+class QtTestMetaDataProvider : public QMetaDataReaderControl
+{
+ Q_OBJECT
+public:
+ QtTestMetaDataProvider(QObject *parent = 0)
+ : QMetaDataReaderControl(parent)
+ , m_available(false)
+ {
+ }
+
+ bool isMetaDataAvailable() const { return m_available; }
+ void setMetaDataAvailable(bool available) {
+ if (m_available != available)
+ emit metaDataAvailableChanged(m_available = available);
+ }
+ QList<QtMultimediaKit::MetaData> availableMetaData() const { return m_data.keys(); }
+
+
+ QVariant metaData(QtMultimediaKit::MetaData key) const { return m_data.value(key); }
+
+ QVariant extendedMetaData(const QString &key) const { return m_extendedData.value(key); }
+
+ QStringList availableExtendedMetaData() const { return m_extendedData.keys(); }
+
+ using QMetaDataReaderControl::metaDataChanged;
+
+ void populateMetaData()
+ {
+ m_available = true;
+ }
+
+ bool m_available;
+ QMap<QtMultimediaKit::MetaData, QVariant> m_data;
+ QMap<QString, QVariant> m_extendedData;
+};
+
+class QtTestMetaDataService : public QMediaService
+{
+ Q_OBJECT
+public:
+ QtTestMetaDataService(QObject *parent = 0):QMediaService(parent), metaDataRef(0), hasMetaData(true)
+ {
+ }
+
+ QMediaControl *requestControl(const char *iid)
+ {
+ if (hasMetaData && qstrcmp(iid, QMetaDataReaderControl_iid) == 0)
+ return &metaData;
+ else
+ return 0;
+ }
+
+ void releaseControl(QMediaControl *)
+ {
+ }
+
+ QtTestMetaDataProvider metaData;
+ int metaDataRef;
+ bool hasMetaData;
+};
+
+class QtTestMediaObject : public QMediaObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int a READ a WRITE setA NOTIFY aChanged)
+ Q_PROPERTY(int b READ b WRITE setB NOTIFY bChanged)
+ Q_PROPERTY(int c READ c WRITE setC NOTIFY cChanged)
+ Q_PROPERTY(int d READ d WRITE setD)
+public:
+ QtTestMediaObject(QMediaService *service = 0): QMediaObject(0, service), m_a(0), m_b(0), m_c(0), m_d(0) {}
+
+ using QMediaObject::addPropertyWatch;
+ using QMediaObject::removePropertyWatch;
+
+ int a() const { return m_a; }
+ void setA(int a) { m_a = a; }
+
+ int b() const { return m_b; }
+ void setB(int b) { m_b = b; }
+
+ int c() const { return m_c; }
+ void setC(int c) { m_c = c; }
+
+ int d() const { return m_d; }
+ void setD(int d) { m_d = d; }
+
+Q_SIGNALS:
+ void aChanged(int a);
+ void bChanged(int b);
+ void cChanged(int c);
+
+private:
+ int m_a;
+ int m_b;
+ int m_c;
+ int m_d;
+};
+#endif //TST_QMEDIAOBJECT_H \ No newline at end of file
diff --git a/tests/auto/qmediaobject/tst_qmediaobject_mmf.cpp b/tests/auto/qmediaobject/tst_qmediaobject_mmf.cpp
new file mode 100644
index 000000000..7cf5622a5
--- /dev/null
+++ b/tests/auto/qmediaobject/tst_qmediaobject_mmf.cpp
@@ -0,0 +1,278 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <tst_qmediaobject_mmf.h>
+
+QT_USE_NAMESPACE
+
+void tst_QMediaObject_mmf::initTestCase_data()
+{
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<QMediaContent>("mediaContent");
+ QTest::addColumn<bool>("metaDataAvailable");
+
+ QTest::newRow("TestDataNull")
+ << false // valid
+ << QMediaContent() // mediaContent
+ << false; // metaDataAvailable
+
+ QTest::newRow("test_amr.amr")
+ << true // valid
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test_amr.amr")) // mediaContent
+ << false; // metaDataAvailable
+
+ QTest::newRow("test_flash_video.flv")
+ << true // valid
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test_flash_video.flv")) // mediaContent
+ << false; // metaDataAvailable
+
+ QTest::newRow("test_invalid_extension_mp4.xyz")
+ << true // valid
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test_invalid_extension_mp4.xyz")) // mediaContent
+ << false; // metaDataAvailable
+
+ QTest::newRow("test_invalid_extension_wav.xyz")
+ << true // valid
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test_invalid_extension_wav.xyz")) // mediaContent
+ << false; // metaDataAvailable
+
+ QTest::newRow("test_mp3.mp3")
+ << true // valid
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test_mp3.mp3")) // mediaContent
+#if !defined(__WINS__) || !defined(__WINSCW__)
+ << true; // metaDataAvailable
+#else
+ << false; // metaDataAvailable
+#endif // !defined(__WINS__) || defined(__WINSCW__)
+
+ QTest::newRow("test_mp3_no_metadata.mp3")
+ << true // valid
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test_mp3_no_metadata.mp3")) // mediaContent
+ << false; // metaDataAvailable
+
+ QTest::newRow("test_mp4.mp4")
+ << true // valid
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test_mp4.mp4")) // mediaContent
+#if defined(__WINS__) || defined(__WINSCW__)
+ << true; // metaDataAvailable
+#else
+ << false; // metaDataAvailable
+#endif // !defined(__WINS__) || defined(__WINSCW__)
+
+ QTest::newRow("test_wav.wav")
+ << true // valid
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test_wav.wav")) // mediaContent
+ << false; // metaDataAvailable
+
+ QTest::newRow("test_wmv9.wmv")
+ << true // valid
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test_wmv9.wmv")) // mediaContent
+ << false; // metaDataAvailable
+
+ QTest::newRow("test youtube stream")
+ << true // valid
+ << QMediaContent(QUrl("rtsp://v3.cache4.c.youtube.com/CkgLENy73wIaPwlU2rm7yu8PFhMYESARFEIJbXYtZ29vZ2xlSARSB3JlbGF0ZWRaDkNsaWNrVGh1bWJuYWlsYPi6_IXT2rvpSgw=/0/0/0/video.3gp")) // mediaContent
+ << false; // metaDataAvailable
+}
+
+void tst_QMediaObject_mmf::initTestCase()
+{
+}
+
+void tst_QMediaObject_mmf::cleanupTestCase()
+{
+}
+
+void tst_QMediaObject_mmf::init()
+{
+ qRegisterMetaType<QMediaContent>("QMediaContent");
+}
+
+void tst_QMediaObject_mmf::cleanup()
+{
+}
+
+void tst_QMediaObject_mmf::isMetaDataAvailable()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(bool, metaDataAvailable);
+ QMediaPlayer player;
+
+ player.setMedia(mediaContent);
+ QTest::qWait(700);
+ QVERIFY(player.isMetaDataAvailable() == metaDataAvailable);
+}
+
+void tst_QMediaObject_mmf::metaData()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(bool, metaDataAvailable);
+ QMediaPlayer player;
+
+ player.setMedia(mediaContent);
+ QTest::qWait(700);
+ const QString artist(QLatin1String("Artist"));
+ const QString title(QLatin1String("Title"));
+
+ if (player.isMetaDataAvailable()) {
+ QCOMPARE(player.metaData(QtMultimediaKit::AlbumArtist).toString(), artist);
+ QCOMPARE(player.metaData(QtMultimediaKit::Title).toString(), title);
+ }
+}
+
+void tst_QMediaObject_mmf::availableMetaData()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(bool, metaDataAvailable);
+ QMediaPlayer player;
+
+ player.setMedia(mediaContent);
+ QTest::qWait(700);
+
+ if (player.isMetaDataAvailable()) {
+ QList<QtMultimediaKit::MetaData> metaDataKeys = player.availableMetaData();
+ QVERIFY(metaDataKeys.count() > 0);
+ QVERIFY(metaDataKeys.contains(QtMultimediaKit::AlbumArtist));
+ QVERIFY(metaDataKeys.contains(QtMultimediaKit::Title));
+ }
+}
+
+void tst_QMediaObject_mmf::extendedMetaData()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QMediaPlayer player;
+
+ player.setMedia(mediaContent);
+ QTest::qWait(700);
+ const QString artist(QLatin1String("Artist"));
+ const QString title(QLatin1String("Title"));
+
+ if (player.isMetaDataAvailable()) {
+ QCOMPARE(player.extendedMetaData(metaDataKeyAsString(QtMultimediaKit::AlbumArtist)).toString(), artist);
+ QCOMPARE(player.extendedMetaData(metaDataKeyAsString(QtMultimediaKit::Title)).toString(), title);
+ }
+}
+
+void tst_QMediaObject_mmf::availableExtendedMetaData()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QMediaPlayer player;
+
+ player.setMedia(mediaContent);
+ QTest::qWait(700);
+ const QString artist(QLatin1String("Artist"));
+ const QString title(QLatin1String("Title"));
+
+ if (player.isMetaDataAvailable()) {
+ QStringList metaDataKeys = player.availableExtendedMetaData();
+ QVERIFY(metaDataKeys.count() > 0);
+/* qWarning() << "metaDataKeys.count: " << metaDataKeys.count();
+ int count = metaDataKeys.count();
+ count = count-1;
+ int i = 0;
+ while(count >= i)
+ {
+ qWarning() << "metaDataKeys "<<i<<"." << metaDataKeys.at(i);
+ i++;
+ }*/
+ QVERIFY(metaDataKeys.contains(metaDataKeyAsString(QtMultimediaKit::AlbumArtist)));
+ QVERIFY(metaDataKeys.contains(metaDataKeyAsString(QtMultimediaKit::Title)));
+ }
+}
+
+QString tst_QMediaObject_mmf::metaDataKeyAsString(QtMultimediaKit::MetaData key) const
+{
+ switch(key) {
+ case QtMultimediaKit::Title: return "title";
+ case QtMultimediaKit::AlbumArtist: return "artist";
+ case QtMultimediaKit::Comment: return "comment";
+ case QtMultimediaKit::Genre: return "genre";
+ case QtMultimediaKit::Year: return "year";
+ case QtMultimediaKit::Copyright: return "copyright";
+ case QtMultimediaKit::AlbumTitle: return "album";
+ case QtMultimediaKit::Composer: return "composer";
+ case QtMultimediaKit::TrackNumber: return "albumtrack";
+ case QtMultimediaKit::AudioBitRate: return "audiobitrate";
+ case QtMultimediaKit::VideoBitRate: return "videobitrate";
+ case QtMultimediaKit::Duration: return "duration";
+ case QtMultimediaKit::MediaType: return "contenttype";
+ case QtMultimediaKit::SubTitle:
+ case QtMultimediaKit::Description:
+ case QtMultimediaKit::Category:
+ case QtMultimediaKit::Date:
+ case QtMultimediaKit::UserRating:
+ case QtMultimediaKit::Keywords:
+ case QtMultimediaKit::Language:
+ case QtMultimediaKit::Publisher:
+ case QtMultimediaKit::ParentalRating:
+ case QtMultimediaKit::RatingOrganisation:
+ case QtMultimediaKit::Size:
+ case QtMultimediaKit::AudioCodec:
+ case QtMultimediaKit::AverageLevel:
+ case QtMultimediaKit::ChannelCount:
+ case QtMultimediaKit::PeakValue:
+ case QtMultimediaKit::SampleRate:
+ case QtMultimediaKit::Author:
+ case QtMultimediaKit::ContributingArtist:
+ case QtMultimediaKit::Conductor:
+ case QtMultimediaKit::Lyrics:
+ case QtMultimediaKit::Mood:
+ case QtMultimediaKit::TrackCount:
+ case QtMultimediaKit::CoverArtUrlSmall:
+ case QtMultimediaKit::CoverArtUrlLarge:
+ case QtMultimediaKit::Resolution:
+ case QtMultimediaKit::PixelAspectRatio:
+ case QtMultimediaKit::VideoFrameRate:
+ case QtMultimediaKit::VideoCodec:
+ case QtMultimediaKit::PosterUrl:
+ case QtMultimediaKit::ChapterNumber:
+ case QtMultimediaKit::Director:
+ case QtMultimediaKit::LeadPerformer:
+ case QtMultimediaKit::Writer:
+ case QtMultimediaKit::CameraManufacturer:
+ case QtMultimediaKit::CameraModel:
+ case QtMultimediaKit::Event:
+ case QtMultimediaKit::Subject:
+ default:
+ break;
+ }
+
+ return QString();
+}
diff --git a/tests/auto/qmediaobject/tst_qmediaobject_mmf.h b/tests/auto/qmediaobject/tst_qmediaobject_mmf.h
new file mode 100644
index 000000000..1a381dec8
--- /dev/null
+++ b/tests/auto/qmediaobject/tst_qmediaobject_mmf.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TST_QMEDIAOBJECT_MMF_H
+#define TST_QMEDIAOBJECT_MMF_H
+
+#include <QtTest/QtTest>
+#include <QtCore>
+#include <QtGui>
+
+#include <qtmedianamespace.h>
+#include <QMediaPlayer>
+#include <QMediaPlayerControl>
+#include <QMediaPlaylist>
+#include <QMediaService>
+#include <QMediaStreamsControl>
+#include <QVideoWidget>
+
+QT_USE_NAMESPACE
+
+class tst_QMediaObject_mmf : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase_data();
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void isMetaDataAvailable();
+ void metaData();
+ void availableMetaData();
+ void extendedMetaData();
+ void availableExtendedMetaData();
+
+private:
+ QString metaDataKeyAsString(QtMultimediaKit::MetaData key) const;
+};
+
+#endif // TST_QMEDIAOBJECT_MMF_H
diff --git a/tests/auto/qmediaobject/tst_qmediaobject_xa.cpp b/tests/auto/qmediaobject/tst_qmediaobject_xa.cpp
new file mode 100644
index 000000000..810a414b8
--- /dev/null
+++ b/tests/auto/qmediaobject/tst_qmediaobject_xa.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tst_qmediaobject_xa.h"
+
+QT_USE_NAMESPACE
+
+#define WAIT_FOR_CONDITION(a,e) \
+ for (int _i = 0; _i < 500; _i += 1) { \
+ if ((a) == (e)) break; \
+ QTest::qWait(10);}
+
+
+#define WAIT_LONG_FOR_CONDITION(a,e) \
+ for (int _i = 0; _i < 1800; _i += 1) { \
+ if ((a) == (e)) break; \
+ QTest::qWait(100);}
+
+Q_DECLARE_METATYPE(QtMultimediaKit::MetaData)
+
+void tst_QMetadata_xa::initTestCase_data()
+{
+ QTest::addColumn<QMediaContent>("mediaContent");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<QtMultimediaKit::MetaData>("key");
+ QTest::addColumn<qint64>("intValue");
+ QTest::addColumn<QString>("strValue");
+
+ QTest::newRow("testmp3.mp3 - No Metadata")
+ << QMediaContent(QUrl("file:///C:/data/testfiles/test.mp3")) // mediaContent
+ << 0 //count
+ << QtMultimediaKit::Title //key - irrelavant when count 0
+ << qint64(-1) //intValue
+ << QString(); //strValue
+
+ QTest::newRow("JapJap.mp3 - Title")
+ << QMediaContent(QUrl("file:///C:/data/testfiles/JapJap.mp3")) // mediaContent
+ << -1 //count - ignore
+ << QtMultimediaKit::Title //key
+ << qint64(-1) //intValue
+ << QString("JapJap");//strValue
+
+ QTest::newRow("JapJap.mp3 - Artist")
+ << QMediaContent(QUrl("file:///C:/data/testfiles/JapJap.mp3")) // mediaContent
+ << -1 //count - ignore
+ << QtMultimediaKit::AlbumArtist //key
+ << qint64(-1) //intValue
+ << QString("Screaming trees");//strValue
+
+ QTest::newRow("JapJap.mp3 - Album")
+ << QMediaContent(QUrl("file:///C:/data/testfiles/JapJap.mp3")) // mediaContent
+ << -1 //count - ignore
+ << QtMultimediaKit::AlbumTitle //key
+ << qint64(-1) //intValue
+ << QString("Sweet oblivion"); //strValue
+
+ QTest::newRow("JapJap.mp3 - CoverArt")
+ << QMediaContent(QUrl("file:///C:/data/testfiles/JapJap.mp3")) // mediaContent
+ << -1 //count - ignore
+ << QtMultimediaKit::CoverArtImage //key
+ << qint64(28521) //intValue
+ << QString("C:/data/testfiles/JapJapCoverArt.jpeg"); //strValue
+}
+
+void tst_QMetadata_xa::initTestCase()
+{
+ m_player = new QMediaPlayer();
+
+ // Symbian back end needs coecontrol for creation.
+ m_widget = new QVideoWidget();
+ //m_widget->setMediaObject(m_player);
+ m_widget->show();
+ runonce = false;
+}
+
+void tst_QMetadata_xa::cleanupTestCase()
+{
+ delete m_player;
+ delete m_widget;
+}
+
+void tst_QMetadata_xa::init()
+{
+ qRegisterMetaType<QMediaContent>("QMediaContent");
+ qRegisterMetaType<QtMultimediaKit::MetaData>("QtMultimediaKit::MetaData");
+}
+
+void tst_QMetadata_xa::cleanup()
+{
+}
+
+void tst_QMetadata_xa::testMetadata()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(int, count);
+ QFETCH_GLOBAL(QtMultimediaKit::MetaData, key);
+ QFETCH_GLOBAL(QString, strValue);
+ QFETCH_GLOBAL(qint64, intValue);
+
+ QSignalSpy spy(m_player, SIGNAL(metaDataAvailableChanged(bool)));
+ m_player->setMedia(mediaContent);
+
+ WAIT_FOR_CONDITION(spy.count(), 1);
+ //get metadata count
+ QList<QtMultimediaKit::MetaData> mdList = m_player->availableMetaData ();
+ QStringList amdList = m_player->availableExtendedMetaData();
+
+ int numMetadataItems = mdList.size() + amdList.size();
+ if (count>=0) //-1 indicate ignore count
+ QVERIFY(count==numMetadataItems);
+
+ if (numMetadataItems>0 && !strValue.isEmpty()) {
+ QVariant val = m_player->metaData(key);
+
+ if(key == QtMultimediaKit::CoverArtImage)
+ val.value<QImage>().save(strValue);
+ else
+ QVERIFY(strValue == val.toString());
+ }
+}
diff --git a/tests/auto/qmediaobject/tst_qmediaobject_xa.h b/tests/auto/qmediaobject/tst_qmediaobject_xa.h
new file mode 100644
index 000000000..81dc85095
--- /dev/null
+++ b/tests/auto/qmediaobject/tst_qmediaobject_xa.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TST_QMEDIAOBJECT_XA_H
+#define TST_QMEDIAOBJECT_XA_H
+
+#include <QtTest/QtTest>
+#include <QtCore>
+#include <QtGui>
+
+#include <QMediaPlayer>
+#include <QMediaPlayerControl>
+#include <QMediaPlaylist>
+#include <QMediaService>
+#include <QMediaStreamsControl>
+#include <QVideoWidget>
+
+#include <QList>
+#include <QStringList>
+
+QT_USE_NAMESPACE
+
+class tst_QMetadata_xa: public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase_data();
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void testMetadata();
+
+
+private:
+ void displayImage(QImage);
+ QMediaPlayer *m_player;
+ QVideoWidget *m_widget;
+ bool runonce;
+};
+
+#endif //TST_QMEDIAOBJECT_XA_H
diff --git a/tests/auto/qmediaplayer/main.cpp b/tests/auto/qmediaplayer/main.cpp
new file mode 100755
index 000000000..b4dd5c470
--- /dev/null
+++ b/tests/auto/qmediaplayer/main.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCore/qcoreapplication.h>
+#include <QtTest/QtTest>
+
+#include "tst_qmediaplayer.h"
+
+#ifdef Q_OS_SYMBIAN
+#include "tst_qmediaplayer_xa.h"
+#include "tst_qmediaplayer_s60.h"
+#endif
+
+int main(int argc, char**argv)
+{
+ QApplication app(argc,argv);
+ int ret;
+ tst_QMediaPlayer test_api;
+ ret = QTest::qExec(&test_api, argc, argv);
+#ifdef Q_OS_SYMBIAN
+ char *new_argv[3];
+ QString str = "C:\\data\\" + QFileInfo(QCoreApplication::applicationFilePath()).baseName() + "_s60.log";
+ QByteArray bytes = str.toAscii();
+ char arg1[] = "-o";
+ new_argv[0] = argv[0];
+ new_argv[1] = arg1;
+ new_argv[2] = bytes.data();
+ tst_QMediaPlayer_xa test_xa;
+ ret = QTest::qExec(&test_xa, 3, new_argv);
+ char *new_argv1[3];
+ QString str1 = "C:\\data\\" + QFileInfo(QCoreApplication::applicationFilePath()).baseName() + "_s60.log";
+ QByteArray bytes1 = str1.toAscii();
+ char arg2[] = "-o";
+ new_argv1[0] = argv[0];
+ new_argv1[1] = arg2;
+ new_argv1[2] = bytes1.data();
+ tst_QMediaPlayer_s60 test_s60;
+ ret = QTest::qExec(&test_s60, 3, new_argv1);
+#endif
+ return ret;
+}
diff --git a/tests/auto/qmediaplayer/qmediaplayer.pro b/tests/auto/qmediaplayer/qmediaplayer.pro
new file mode 100644
index 000000000..b624afd91
--- /dev/null
+++ b/tests/auto/qmediaplayer/qmediaplayer.pro
@@ -0,0 +1,25 @@
+load(qttest_p4)
+
+QT += network multimediakit-private
+
+# TARGET = tst_qmediaplayer
+# CONFIG += testcase
+
+symbian {
+ TARGET.CAPABILITY = NetworkServices
+ testFiles.sources = testfiles/*
+ testFiles.path = /Data/testfiles
+ DEPLOYMENT += testFiles
+ contains(openmaxal_symbian_enabled, no) {
+ DEFINES += HAS_OPENMAXAL_MEDIAPLAY_BACKEND
+ HEADERS += tst_qmediaplayer_xa.h
+ SOURCES += tst_qmediaplayer_xa.cpp
+ } else {
+ HEADERS += tst_qmediaplayer_s60.h
+ SOURCES += tst_qmediaplayer_s60.cpp
+ }
+}
+
+HEADERS += tst_qmediaplayer.h
+SOURCES += main.cpp tst_qmediaplayer.cpp
+
diff --git a/tests/auto/qmediaplayer/tst_qmediaplayer.cpp b/tests/auto/qmediaplayer/tst_qmediaplayer.cpp
new file mode 100644
index 000000000..4cef0e354
--- /dev/null
+++ b/tests/auto/qmediaplayer/tst_qmediaplayer.cpp
@@ -0,0 +1,1019 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include "tst_qmediaplayer.h"
+
+#include <qgraphicsvideoitem.h>
+#include <QtNetwork/qnetworkconfigmanager.h>
+
+// Encouraging successful diversity through copy and paste.
+#ifndef QTRY_COMPARE
+#define QTRY_COMPARE(__expr, __expected) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 5000; \
+ if ((__expr) != (__expected)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ QCOMPARE(__expr, __expected); \
+ } while(0)
+#endif
+
+#ifndef QTRY_VERIFY
+#define QTRY_VERIFY(__expr) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 5000; \
+ if (!(__expr)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ QVERIFY(__expr); \
+ } while(0)
+#endif
+
+QT_USE_NAMESPACE
+
+void tst_QMediaPlayer::initTestCase_data()
+{
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<QMediaPlayer::State>("state");
+ QTest::addColumn<QMediaPlayer::MediaStatus>("status");
+ QTest::addColumn<QMediaContent>("mediaContent");
+ QTest::addColumn<qint64>("duration");
+ QTest::addColumn<qint64>("position");
+ QTest::addColumn<bool>("seekable");
+ QTest::addColumn<int>("volume");
+ QTest::addColumn<bool>("muted");
+ QTest::addColumn<bool>("videoAvailable");
+ QTest::addColumn<int>("bufferStatus");
+ QTest::addColumn<qreal>("playbackRate");
+ QTest::addColumn<QMediaPlayer::Error>("error");
+ QTest::addColumn<QString>("errorString");
+
+ QTest::newRow("invalid") << false << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus <<
+ QMediaContent() << qint64(0) << qint64(0) << false << 0 << false << false << 0 <<
+ qreal(0) << QMediaPlayer::NoError << QString();
+ QTest::newRow("valid+null") << true << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus <<
+ QMediaContent() << qint64(0) << qint64(0) << false << 0 << false << false << 50 <<
+ qreal(0) << QMediaPlayer::NoError << QString();
+ QTest::newRow("valid+content+stopped") << true << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus <<
+ QMediaContent(QUrl("file:///some.mp3")) << qint64(0) << qint64(0) << false << 50 << false << false << 0 <<
+ qreal(1) << QMediaPlayer::NoError << QString();
+ QTest::newRow("valid+content+playing") << true << QMediaPlayer::PlayingState << QMediaPlayer::LoadedMedia <<
+ QMediaContent(QUrl("file:///some.mp3")) << qint64(10000) << qint64(10) << true << 50 << true << false << 0 <<
+ qreal(1) << QMediaPlayer::NoError << QString();
+ QTest::newRow("valid+content+paused") << true << QMediaPlayer::PausedState << QMediaPlayer::LoadedMedia <<
+ QMediaContent(QUrl("file:///some.mp3")) << qint64(10000) << qint64(10) << true << 50 << true << false << 0 <<
+ qreal(1) << QMediaPlayer::NoError << QString();
+ QTest::newRow("valud+streaming") << true << QMediaPlayer::PlayingState << QMediaPlayer::LoadedMedia <<
+ QMediaContent(QUrl("http://example.com/stream")) << qint64(10000) << qint64(10000) << false << 50 << false << true << 0 <<
+ qreal(1) << QMediaPlayer::NoError << QString();
+ QTest::newRow("valid+error") << true << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus <<
+ QMediaContent(QUrl("http://example.com/stream")) << qint64(0) << qint64(0) << false << 50 << false << false << 0 <<
+ qreal(0) << QMediaPlayer::ResourceError << QString("Resource unavailable");
+}
+
+void tst_QMediaPlayer::initTestCase()
+{
+ qRegisterMetaType<QMediaPlayer::State>("QMediaPlayer::State");
+ qRegisterMetaType<QMediaPlayer::Error>("QMediaPlayer::Error");
+ qRegisterMetaType<QMediaPlayer::MediaStatus>("QMediaPlayer::MediaStatus");
+ qRegisterMetaType<QMediaContent>("QMediaContent");
+
+ mockService = new MockPlayerService;
+ mockProvider = new MockProvider(mockService);
+ player = new QMediaPlayer(0, 0, mockProvider);
+}
+
+void tst_QMediaPlayer::cleanupTestCase()
+{
+ delete player;
+}
+
+void tst_QMediaPlayer::init()
+{
+ mockService->reset();
+}
+
+void tst_QMediaPlayer::cleanup()
+{
+}
+
+void tst_QMediaPlayer::testNullService()
+{
+ MockProvider provider(0);
+ QMediaPlayer player(0, 0, &provider);
+
+ const QIODevice *nullDevice = 0;
+
+ QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(player.mediaStream(), nullDevice);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(player.duration(), qint64(-1));
+ QCOMPARE(player.position(), qint64(0));
+ QCOMPARE(player.volume(), 0);
+ QCOMPARE(player.isMuted(), false);
+ QCOMPARE(player.isVideoAvailable(), false);
+ QCOMPARE(player.bufferStatus(), 0);
+ QCOMPARE(player.isSeekable(), false);
+ QCOMPARE(player.playbackRate(), qreal(0));
+ QCOMPARE(player.error(), QMediaPlayer::ServiceMissingError);
+ QCOMPARE(player.isAvailable(), false);
+ QCOMPARE(player.availabilityError(), QtMultimediaKit::ServiceMissingError);
+
+ {
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+
+ QSignalSpy spy(&player, SIGNAL(mediaChanged(QMediaContent)));
+ QFile file;
+
+ player.setMedia(mediaContent, &file);
+ QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(player.mediaStream(), nullDevice);
+ QCOMPARE(spy.count(), 0);
+ } {
+ QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+
+ player.play();
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+
+ player.pause();
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+
+ player.stop();
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+ } {
+ QFETCH_GLOBAL(int, volume);
+ QFETCH_GLOBAL(bool, muted);
+
+ QSignalSpy volumeSpy(&player, SIGNAL(volumeChanged(int)));
+ QSignalSpy mutingSpy(&player, SIGNAL(mutedChanged(bool)));
+
+ player.setVolume(volume);
+ QCOMPARE(player.volume(), 0);
+ QCOMPARE(volumeSpy.count(), 0);
+
+ player.setMuted(muted);
+ QCOMPARE(player.isMuted(), false);
+ QCOMPARE(mutingSpy.count(), 0);
+ } {
+ QFETCH_GLOBAL(qint64, position);
+
+ QSignalSpy spy(&player, SIGNAL(positionChanged(qint64)));
+
+ player.setPosition(position);
+ QCOMPARE(player.position(), qint64(0));
+ QCOMPARE(spy.count(), 0);
+ } {
+ QFETCH_GLOBAL(qreal, playbackRate);
+
+ QSignalSpy spy(&player, SIGNAL(playbackRateChanged(qreal)));
+
+ player.setPlaybackRate(playbackRate);
+ QCOMPARE(player.playbackRate(), qreal(0));
+ QCOMPARE(spy.count(), 0);
+ } {
+ QMediaPlaylist playlist;
+ player.setPlaylist(&playlist);
+
+ QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(QMediaContent)));
+ QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+
+ playlist.addMedia(QUrl("http://example.com/stream"));
+ playlist.addMedia(QUrl("file:///some.mp3"));
+
+ playlist.setCurrentIndex(0);
+ QCOMPARE(playlist.currentIndex(), 0);
+ QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(mediaSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+
+ playlist.next();
+ QCOMPARE(playlist.currentIndex(), 1);
+ QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(mediaSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+ }
+}
+
+void tst_QMediaPlayer::testValid()
+{
+ /*
+ QFETCH_GLOBAL(bool, valid);
+
+ mockService->setIsValid(valid);
+ QCOMPARE(player->isValid(), valid);
+ */
+}
+
+void tst_QMediaPlayer::testMedia()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+
+ mockService->setMedia(mediaContent);
+ QCOMPARE(player->media(), mediaContent);
+
+ QBuffer stream;
+ player->setMedia(mediaContent, &stream);
+ QCOMPARE(player->media(), mediaContent);
+ QCOMPARE((QBuffer*)player->mediaStream(), &stream);
+}
+
+void tst_QMediaPlayer::testDuration()
+{
+ QFETCH_GLOBAL(qint64, duration);
+
+ mockService->setDuration(duration);
+ QVERIFY(player->duration() == duration);
+}
+
+void tst_QMediaPlayer::testPosition()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(bool, seekable);
+ QFETCH_GLOBAL(qint64, position);
+ QFETCH_GLOBAL(qint64, duration);
+
+ mockService->setIsValid(valid);
+ mockService->setSeekable(seekable);
+ mockService->setPosition(position);
+ mockService->setDuration(duration);
+ QVERIFY(player->isSeekable() == seekable);
+ QVERIFY(player->position() == position);
+ QVERIFY(player->duration() == duration);
+
+ if (seekable) {
+ { QSignalSpy spy(player, SIGNAL(positionChanged(qint64)));
+ player->setPosition(position);
+ QCOMPARE(player->position(), position);
+ QCOMPARE(spy.count(), 0); }
+
+ mockService->setPosition(position);
+ { QSignalSpy spy(player, SIGNAL(positionChanged(qint64)));
+ player->setPosition(0);
+ QCOMPARE(player->position(), qint64(0));
+ QCOMPARE(spy.count(), position == 0 ? 0 : 1); }
+
+ mockService->setPosition(position);
+ { QSignalSpy spy(player, SIGNAL(positionChanged(qint64)));
+ player->setPosition(duration);
+ QCOMPARE(player->position(), duration);
+ QCOMPARE(spy.count(), position == duration ? 0 : 1); }
+
+ mockService->setPosition(position);
+ { QSignalSpy spy(player, SIGNAL(positionChanged(qint64)));
+ player->setPosition(-1);
+ QCOMPARE(player->position(), qint64(0));
+ QCOMPARE(spy.count(), position == 0 ? 0 : 1); }
+
+ mockService->setPosition(position);
+ { QSignalSpy spy(player, SIGNAL(positionChanged(qint64)));
+ player->setPosition(duration + 1);
+ QCOMPARE(player->position(), duration);
+ QCOMPARE(spy.count(), position == duration ? 0 : 1); }
+ }
+ else {
+ QSignalSpy spy(player, SIGNAL(positionChanged(qint64)));
+ player->setPosition(position);
+
+ QCOMPARE(player->position(), position);
+ QCOMPARE(spy.count(), 0);
+ }
+}
+
+void tst_QMediaPlayer::testVolume()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(int, volume);
+
+ mockService->setVolume(volume);
+ QVERIFY(player->volume() == volume);
+
+ if (valid) {
+ { QSignalSpy spy(player, SIGNAL(volumeChanged(int)));
+ player->setVolume(10);
+ QCOMPARE(player->volume(), 10);
+ QCOMPARE(spy.count(), 1); }
+
+ { QSignalSpy spy(player, SIGNAL(volumeChanged(int)));
+ player->setVolume(-1000);
+ QCOMPARE(player->volume(), 0);
+ QCOMPARE(spy.count(), 1); }
+
+ { QSignalSpy spy(player, SIGNAL(volumeChanged(int)));
+ player->setVolume(100);
+ QCOMPARE(player->volume(), 100);
+ QCOMPARE(spy.count(), 1); }
+
+ { QSignalSpy spy(player, SIGNAL(volumeChanged(int)));
+ player->setVolume(1000);
+ QCOMPARE(player->volume(), 100);
+ QCOMPARE(spy.count(), 0); }
+ }
+}
+
+void tst_QMediaPlayer::testMuted()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(bool, muted);
+ QFETCH_GLOBAL(int, volume);
+
+ if (valid) {
+ mockService->setMuted(muted);
+ mockService->setVolume(volume);
+ QVERIFY(player->isMuted() == muted);
+
+ QSignalSpy spy(player, SIGNAL(mutedChanged(bool)));
+ player->setMuted(!muted);
+ QCOMPARE(player->isMuted(), !muted);
+ QCOMPARE(player->volume(), volume);
+ QCOMPARE(spy.count(), 1);
+ }
+}
+
+void tst_QMediaPlayer::testVideoAvailable()
+{
+ QFETCH_GLOBAL(bool, videoAvailable);
+
+ mockService->setVideoAvailable(videoAvailable);
+ QVERIFY(player->isVideoAvailable() == videoAvailable);
+}
+
+void tst_QMediaPlayer::testBufferStatus()
+{
+ QFETCH_GLOBAL(int, bufferStatus);
+
+ mockService->setBufferStatus(bufferStatus);
+ QVERIFY(player->bufferStatus() == bufferStatus);
+}
+
+void tst_QMediaPlayer::testSeekable()
+{
+ QFETCH_GLOBAL(bool, seekable);
+
+ mockService->setSeekable(seekable);
+ QVERIFY(player->isSeekable() == seekable);
+}
+
+void tst_QMediaPlayer::testPlaybackRate()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(qreal, playbackRate);
+
+ if (valid) {
+ mockService->setPlaybackRate(playbackRate);
+ QVERIFY(player->playbackRate() == playbackRate);
+
+ QSignalSpy spy(player, SIGNAL(playbackRateChanged(qreal)));
+ player->setPlaybackRate(playbackRate + 0.5f);
+ QCOMPARE(player->playbackRate(), playbackRate + 0.5f);
+ QCOMPARE(spy.count(), 1);
+ }
+}
+
+void tst_QMediaPlayer::testError()
+{
+ QFETCH_GLOBAL(QMediaPlayer::Error, error);
+
+ mockService->setError(error);
+ QVERIFY(player->error() == error);
+}
+
+void tst_QMediaPlayer::testErrorString()
+{
+ QFETCH_GLOBAL(QString, errorString);
+
+ mockService->setErrorString(errorString);
+ QVERIFY(player->errorString() == errorString);
+}
+
+void tst_QMediaPlayer::testIsAvailable()
+{
+ QCOMPARE(player->isAvailable(), true);
+ QCOMPARE(player->availabilityError(), QtMultimediaKit::NoError);
+}
+
+void tst_QMediaPlayer::testService()
+{
+ /*
+ QFETCH_GLOBAL(bool, valid);
+
+ mockService->setIsValid(valid);
+
+ if (valid)
+ QVERIFY(player->service() != 0);
+ else
+ QVERIFY(player->service() == 0);
+ */
+}
+
+void tst_QMediaPlayer::testPlay()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(QMediaPlayer::State, state);
+
+ mockService->setIsValid(valid);
+ mockService->setState(state);
+ mockService->setMedia(mediaContent);
+ QVERIFY(player->state() == state);
+ QVERIFY(player->media() == mediaContent);
+
+ QSignalSpy spy(player, SIGNAL(stateChanged(QMediaPlayer::State)));
+
+ player->play();
+
+ if (!valid || mediaContent.isNull()) {
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 0);
+ }
+ else {
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(spy.count(), state == QMediaPlayer::PlayingState ? 0 : 1);
+ }
+}
+
+void tst_QMediaPlayer::testPause()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(QMediaPlayer::State, state);
+
+ mockService->setIsValid(valid);
+ mockService->setState(state);
+ mockService->setMedia(mediaContent);
+ QVERIFY(player->state() == state);
+ QVERIFY(player->media() == mediaContent);
+
+ QSignalSpy spy(player, SIGNAL(stateChanged(QMediaPlayer::State)));
+
+ player->pause();
+
+ if (!valid || mediaContent.isNull()) {
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 0);
+ }
+ else {
+ QCOMPARE(player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(spy.count(), state == QMediaPlayer::PausedState ? 0 : 1);
+ }
+}
+
+void tst_QMediaPlayer::testStop()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(QMediaPlayer::State, state);
+
+ mockService->setState(state);
+ mockService->setMedia(mediaContent);
+ QVERIFY(player->state() == state);
+ QVERIFY(player->media() == mediaContent);
+
+ QSignalSpy spy(player, SIGNAL(stateChanged(QMediaPlayer::State)));
+
+ player->stop();
+
+ if (mediaContent.isNull() || state == QMediaPlayer::StoppedState) {
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 0);
+ }
+ else {
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 1);
+ }
+}
+
+void tst_QMediaPlayer::testMediaStatus()
+{
+ QFETCH_GLOBAL(int, bufferStatus);
+ int bufferSignals = 0;
+
+ player->setNotifyInterval(10);
+
+ mockService->setMediaStatus(QMediaPlayer::NoMedia);
+ mockService->setBufferStatus(bufferStatus);
+
+ AutoConnection connection(
+ player, SIGNAL(bufferStatusChanged(int)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ QSignalSpy statusSpy(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ QSignalSpy bufferSpy(player, SIGNAL(bufferStatusChanged(int)));
+
+ QCOMPARE(player->mediaStatus(), QMediaPlayer::NoMedia);
+
+ mockService->setMediaStatus(QMediaPlayer::LoadingMedia);
+ QCOMPARE(player->mediaStatus(), QMediaPlayer::LoadingMedia);
+ QCOMPARE(statusSpy.count(), 1);
+
+ QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)),
+ QMediaPlayer::LoadingMedia);
+
+ mockService->setMediaStatus(QMediaPlayer::LoadedMedia);
+ QCOMPARE(player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(statusSpy.count(), 2);
+
+ QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)),
+ QMediaPlayer::LoadedMedia);
+
+ // Verify the bufferStatusChanged() signal isn't being emitted.
+ QTestEventLoop::instance().enterLoop(1);
+ QCOMPARE(bufferSpy.count(), 0);
+
+ mockService->setMediaStatus(QMediaPlayer::StalledMedia);
+ QCOMPARE(player->mediaStatus(), QMediaPlayer::StalledMedia);
+ QCOMPARE(statusSpy.count(), 3);
+
+ QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)),
+ QMediaPlayer::StalledMedia);
+
+ // Verify the bufferStatusChanged() signal is being emitted.
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(bufferSpy.count() > bufferSignals);
+ QCOMPARE(bufferSpy.last().value(0).toInt(), bufferStatus);
+ bufferSignals = bufferSpy.count();
+
+ mockService->setMediaStatus(QMediaPlayer::BufferingMedia);
+ QCOMPARE(player->mediaStatus(), QMediaPlayer::BufferingMedia);
+ QCOMPARE(statusSpy.count(), 4);
+
+ QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)),
+ QMediaPlayer::BufferingMedia);
+
+ // Verify the bufferStatusChanged() signal is being emitted.
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(bufferSpy.count() > bufferSignals);
+ QCOMPARE(bufferSpy.last().value(0).toInt(), bufferStatus);
+ bufferSignals = bufferSpy.count();
+
+ mockService->setMediaStatus(QMediaPlayer::BufferedMedia);
+ QCOMPARE(player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(statusSpy.count(), 5);
+
+ QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)),
+ QMediaPlayer::BufferedMedia);
+
+ // Verify the bufferStatusChanged() signal isn't being emitted.
+ QTestEventLoop::instance().enterLoop(1);
+ QCOMPARE(bufferSpy.count(), bufferSignals);
+
+ mockService->setMediaStatus(QMediaPlayer::EndOfMedia);
+ QCOMPARE(player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(statusSpy.count(), 6);
+
+ QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)),
+ QMediaPlayer::EndOfMedia);
+}
+
+void tst_QMediaPlayer::testPlaylist()
+{
+ QMediaContent content0(QUrl(QLatin1String("test://audio/song1.mp3")));
+ QMediaContent content1(QUrl(QLatin1String("test://audio/song2.mp3")));
+ QMediaContent content2(QUrl(QLatin1String("test://video/movie1.mp4")));
+ QMediaContent content3(QUrl(QLatin1String("test://video/movie2.mp4")));
+ QMediaContent content4(QUrl(QLatin1String("test://image/photo.jpg")));
+
+ mockService->setIsValid(true);
+ mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::NoMedia);
+
+ QMediaPlaylist *playlist = new QMediaPlaylist;
+ player->setPlaylist(playlist);
+
+ QSignalSpy stateSpy(player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ QSignalSpy mediaSpy(player, SIGNAL(mediaChanged(QMediaContent)));
+
+ // Test the player does nothing with an empty playlist attached.
+ player->play();
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player->media(), QMediaContent());
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(mediaSpy.count(), 0);
+
+ playlist->addMedia(content0);
+ playlist->addMedia(content1);
+ playlist->addMedia(content2);
+ playlist->addMedia(content3);
+
+ // Test changing the playlist position, changes the current media, but not the playing state.
+ playlist->setCurrentIndex(1);
+ QCOMPARE(player->media(), content1);
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ // Test playing starts with the current media.
+ player->play();
+ QCOMPARE(player->media(), content1);
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 1);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ // Test pausing doesn't change the current media.
+ player->pause();
+ QCOMPARE(player->media(), content1);
+ QCOMPARE(player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(stateSpy.count(), 2);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ // Test stopping doesn't change the current media.
+ player->stop();
+ QCOMPARE(player->media(), content1);
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 3);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ // Test when the player service reaches the end of the current media, the player moves onto
+ // the next item without stopping.
+ player->play();
+ QCOMPARE(player->media(), content1);
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 4);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::EndOfMedia);
+ QCOMPARE(player->media(), content2);
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 4);
+ QCOMPARE(mediaSpy.count(), 2);
+
+ // Test skipping the current media doesn't change the state.
+ playlist->next();
+ QCOMPARE(player->media(), content3);
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 4);
+ QCOMPARE(mediaSpy.count(), 3);
+
+ // Test changing the current media while paused doesn't change the state.
+ player->pause();
+ mockService->setMediaStatus(QMediaPlayer::BufferedMedia);
+ QCOMPARE(player->media(), content3);
+ QCOMPARE(player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(stateSpy.count(), 5);
+ QCOMPARE(mediaSpy.count(), 3);
+
+ playlist->previous();
+ QCOMPARE(player->media(), content2);
+ QCOMPARE(player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(stateSpy.count(), 5);
+ QCOMPARE(mediaSpy.count(), 4);
+
+ // Test changing the current media while stopped doesn't change the state.
+ player->stop();
+ mockService->setMediaStatus(QMediaPlayer::LoadedMedia);
+ QCOMPARE(player->media(), content2);
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 6);
+ QCOMPARE(mediaSpy.count(), 4);
+
+ playlist->next();
+ QCOMPARE(player->media(), content3);
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 6);
+ QCOMPARE(mediaSpy.count(), 5);
+
+ // Test the player is stopped and the current media cleared when it reaches the end of the last
+ // item in the playlist.
+ player->play();
+ QCOMPARE(player->media(), content3);
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 7);
+ QCOMPARE(mediaSpy.count(), 5);
+
+ // Double up the signals to ensure some noise doesn't destabalize things.
+ mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::EndOfMedia);
+ mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::EndOfMedia);
+ QCOMPARE(player->media(), QMediaContent());
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 8);
+ QCOMPARE(mediaSpy.count(), 6);
+
+ // Test starts playing from the start of the playlist if there is no current media selected.
+ player->play();
+ QCOMPARE(player->media(), content0);
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 9);
+ QCOMPARE(mediaSpy.count(), 7);
+
+ // Test deleting the playlist stops the player and clears the media it set.
+ delete playlist;
+ QCOMPARE(player->media(), QMediaContent());
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 10);
+ QCOMPARE(mediaSpy.count(), 8);
+
+ // Test the player works as normal with the playlist removed.
+ player->play();
+ QCOMPARE(player->media(), QMediaContent());
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 10);
+ QCOMPARE(mediaSpy.count(), 8);
+
+ player->setMedia(content1);
+ player->play();
+
+ QCOMPARE(player->media(), content1);
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 11);
+ QCOMPARE(mediaSpy.count(), 9);
+
+ // Test the player can bind to playlist again
+ playlist = new QMediaPlaylist;
+ player->setPlaylist(playlist);
+
+ QCOMPARE(player->media(), QMediaContent());
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+
+ playlist->addMedia(content0);
+ playlist->addMedia(content1);
+ playlist->addMedia(content2);
+ playlist->addMedia(content3);
+
+ playlist->setCurrentIndex(1);
+ QCOMPARE(player->media(), content1);
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+
+ // Test attaching the new playlist,
+ // player should detach the current one
+ QMediaPlaylist *playlist2 = new QMediaPlaylist;
+ playlist2->addMedia(content1);
+ playlist2->addMedia(content2);
+ playlist2->addMedia(content3);
+ playlist2->setCurrentIndex(2);
+
+ player->play();
+ player->setPlaylist(playlist2);
+ QCOMPARE(player->media(), playlist2->currentMedia());
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+
+ playlist2->setCurrentIndex(1);
+ QCOMPARE(player->media(), playlist2->currentMedia());
+
+ {
+ QMediaPlaylist playlist;
+ playlist.addMedia(content1);
+ playlist.addMedia(content2);
+ playlist.addMedia(content3);
+ playlist.setCurrentIndex(1);
+
+ player->setPlaylist(&playlist);
+ QCOMPARE(player->playlist(), &playlist);
+ QCOMPARE(player->media(), content2);
+ } //playlist should be detached now
+
+ QVERIFY(player->playlist() == 0);
+ QCOMPARE(player->media(), QMediaContent());
+
+ // Test when the player service encounters an invalid media, the player moves onto
+ // the next item without stopping
+ {
+ QSignalSpy ss(player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ QSignalSpy ms(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+
+ player->setPlaylist(playlist);
+ player->play();
+ QCOMPARE(ss.count(), 1);
+
+ mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::InvalidMedia);
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(player->mediaStatus(), QMediaPlayer::InvalidMedia);
+ QCOMPARE(ss.count(), 1);
+ QCOMPARE(ms.count(), 1);
+
+ // NOTE: status should begin transitioning through to BufferedMedia.
+ QCOMPARE(player->media(), content2);
+ }
+
+}
+
+void tst_QMediaPlayer::testNetworkAccess()
+{
+ QNetworkConfigurationManager manager;
+ QList<QNetworkConfiguration> configs = manager.allConfigurations();
+
+ if (configs.count() >= 1) {
+ QSignalSpy spy(player, SIGNAL(networkConfigurationChanged(QNetworkConfiguration)));
+ int index = qFloor((configs.count())/2);
+ player->setNetworkConfigurations(configs);
+ mockService->selectCurrentConfiguration(configs.at(index));
+
+ QVERIFY(spy.count() == 1);
+ QList<QVariant> args = spy.takeFirst();
+ QNetworkConfiguration config = args.at(0).value<QNetworkConfiguration>();
+ QCOMPARE(config.identifier() , configs.at(index).identifier());
+ QCOMPARE(player->currentNetworkConfiguration().identifier() , config.identifier());
+ }
+
+ // invalidate current network configuration
+ QSignalSpy spy(player, SIGNAL(networkConfigurationChanged(QNetworkConfiguration)));
+ mockService->selectCurrentConfiguration(QNetworkConfiguration());
+ QVERIFY(spy.count() == 1);
+ QList<QVariant> args = spy.takeFirst();
+ QNetworkConfiguration config = args.at(0).value<QNetworkConfiguration>();
+ QVERIFY(config.isValid() == false);
+ QVERIFY(player->currentNetworkConfiguration().isValid() == false);
+}
+
+void tst_QMediaPlayer::testSetVideoOutput()
+{
+ QVideoWidget widget;
+ QGraphicsVideoItem item;
+ MockVideoSurface surface;
+
+ MockPlayerService service;
+ MockProvider provider(&service);
+ provider.deleteServiceOnRelease = false;
+ QMediaPlayer player(0, 0, &provider);
+
+ player.setVideoOutput(&widget);
+ QVERIFY(widget.mediaObject() == &player);
+
+ player.setVideoOutput(&item);
+ QVERIFY(widget.mediaObject() == 0);
+ QVERIFY(item.mediaObject() == &player);
+
+ player.setVideoOutput(reinterpret_cast<QVideoWidget *>(0));
+ QVERIFY(item.mediaObject() == 0);
+
+ player.setVideoOutput(&widget);
+ QVERIFY(widget.mediaObject() == &player);
+
+ player.setVideoOutput(reinterpret_cast<QGraphicsVideoItem *>(0));
+ QVERIFY(widget.mediaObject() == 0);
+
+ player.setVideoOutput(&surface);
+ QVERIFY(service.rendererControl->surface() == &surface);
+
+ player.setVideoOutput(reinterpret_cast<QAbstractVideoSurface *>(0));
+ QVERIFY(service.rendererControl->surface() == 0);
+
+ player.setVideoOutput(&surface);
+ QVERIFY(service.rendererControl->surface() == &surface);
+
+ player.setVideoOutput(&widget);
+ QVERIFY(service.rendererControl->surface() == 0);
+ QVERIFY(widget.mediaObject() == &player);
+
+ player.setVideoOutput(&surface);
+ QVERIFY(service.rendererControl->surface() == &surface);
+ QVERIFY(widget.mediaObject() == 0);
+}
+
+
+void tst_QMediaPlayer::testSetVideoOutputNoService()
+{
+ QVideoWidget widget;
+ QGraphicsVideoItem item;
+ MockVideoSurface surface;
+
+ MockProvider provider(0);
+ QMediaPlayer player(0, 0, &provider);
+
+ player.setVideoOutput(&widget);
+ QVERIFY(widget.mediaObject() == 0);
+
+ player.setVideoOutput(&item);
+ QVERIFY(item.mediaObject() == 0);
+
+ player.setVideoOutput(&surface);
+ // Nothing we can verify here other than it doesn't assert.
+}
+
+void tst_QMediaPlayer::testSetVideoOutputNoControl()
+{
+ QVideoWidget widget;
+ QGraphicsVideoItem item;
+ MockVideoSurface surface;
+
+ MockPlayerService service;
+ service.rendererRef = 1;
+ service.windowRef = 1;
+
+ MockProvider provider(&service);
+ provider.deleteServiceOnRelease = false;
+ QMediaPlayer player(0, 0, &provider);
+
+ player.setVideoOutput(&widget);
+ QVERIFY(widget.mediaObject() == 0);
+
+ player.setVideoOutput(&item);
+ QVERIFY(item.mediaObject() == 0);
+
+ player.setVideoOutput(&surface);
+ QVERIFY(service.rendererControl->surface() == 0);
+}
+
+void tst_QMediaPlayer::testSetVideoOutputDestruction()
+{
+ MockVideoSurface surface;
+
+ MockPlayerService service;
+ MockProvider provider(&service);
+ provider.deleteServiceOnRelease = false;
+
+ {
+ QMediaPlayer player(0, 0, &provider);
+ player.setVideoOutput(&surface);
+ QVERIFY(service.rendererControl->surface() == &surface);
+ QCOMPARE(service.rendererRef, 1);
+ }
+ QVERIFY(service.rendererControl->surface() == 0);
+ QCOMPARE(service.rendererRef, 0);
+}
+
+void tst_QMediaPlayer::testPositionPropertyWatch()
+{
+ QMediaContent content0(QUrl(QLatin1String("test://audio/song1.mp3")));
+ QMediaContent content1(QUrl(QLatin1String("test://audio/song2.mp3")));
+
+ mockService->setIsValid(true);
+ mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::NoMedia);
+
+ QMediaPlaylist *playlist = new QMediaPlaylist;
+
+ playlist->addMedia(content0);
+ playlist->addMedia(content1);
+
+ player->setPlaylist(playlist);
+ player->setNotifyInterval(5);
+
+ player->play();
+ QSignalSpy positionSpy(player, SIGNAL(positionChanged(qint64)));
+ playlist->next();
+ QCOMPARE(player->state(), QMediaPlayer::PlayingState);
+ QTRY_VERIFY(positionSpy.count() > 0);
+
+ playlist->next();
+ QCOMPARE(player->state(), QMediaPlayer::StoppedState);
+
+ positionSpy.clear();
+ QTRY_COMPARE(positionSpy.count(), 0);
+}
+
+void tst_QMediaPlayer::debugEnums()
+{
+ QTest::ignoreMessage(QtDebugMsg, "QMediaPlayer::PlayingState ");
+ qDebug() << QMediaPlayer::PlayingState;
+ QTest::ignoreMessage(QtDebugMsg, "QMediaPlayer::NoMedia ");
+ qDebug() << QMediaPlayer::NoMedia;
+ QTest::ignoreMessage(QtDebugMsg, "QMediaPlayer::NetworkError ");
+ qDebug() << QMediaPlayer::NetworkError;
+}
+
+
diff --git a/tests/auto/qmediaplayer/tst_qmediaplayer.h b/tests/auto/qmediaplayer/tst_qmediaplayer.h
new file mode 100755
index 000000000..6371ac3ff
--- /dev/null
+++ b/tests/auto/qmediaplayer/tst_qmediaplayer.h
@@ -0,0 +1,435 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef TST_QMEDIAPLAYER_H
+#define TST_QMEDIAPLAYER_H
+
+#include <QtTest/QtTest>
+#include <QtCore/qdebug.h>
+#include <QtCore/qbuffer.h>
+#include <QtNetwork/qnetworkconfiguration.h>
+
+#include <qabstractvideosurface.h>
+#include <qmediaplayer.h>
+#include <qmediaplayercontrol.h>
+#include <qmediaplaylist.h>
+#include <qmediaservice.h>
+#include <qmediastreamscontrol.h>
+#include <qmedianetworkaccesscontrol.h>
+#include <qvideorenderercontrol.h>
+#include <qvideowindowcontrol.h>
+
+QT_USE_NAMESPACE
+
+class AutoConnection
+{
+public:
+ AutoConnection(QObject *sender, const char *signal, QObject *receiver, const char *method)
+ : sender(sender), signal(signal), receiver(receiver), method(method)
+ {
+ QObject::connect(sender, signal, receiver, method);
+ }
+
+ ~AutoConnection()
+ {
+ QObject::disconnect(sender, signal, receiver, method);
+ }
+
+private:
+ QObject *sender;
+ const char *signal;
+ QObject *receiver;
+ const char *method;
+};
+
+
+class MockPlayerControl : public QMediaPlayerControl
+{
+ friend class MockPlayerService;
+
+public:
+ MockPlayerControl():QMediaPlayerControl(0) {}
+
+ QMediaPlayer::State state() const { return _state; }
+ QMediaPlayer::MediaStatus mediaStatus() const { return _mediaStatus; }
+
+ qint64 duration() const { return _duration; }
+
+ qint64 position() const { return _position; }
+
+ void setPosition(qint64 position) { if (position != _position) emit positionChanged(_position = position); }
+
+ int volume() const { return _volume; }
+ void setVolume(int volume) { emit volumeChanged(_volume = volume); }
+
+ bool isMuted() const { return _muted; }
+ void setMuted(bool muted) { if (muted != _muted) emit mutedChanged(_muted = muted); }
+
+ int bufferStatus() const { return _bufferStatus; }
+
+ bool isAudioAvailable() const { return _audioAvailable; }
+ bool isVideoAvailable() const { return _videoAvailable; }
+
+ bool isSeekable() const { return _isSeekable; }
+ QMediaTimeRange availablePlaybackRanges() const { return QMediaTimeRange(_seekRange.first, _seekRange.second); }
+ void setSeekRange(qint64 minimum, qint64 maximum) { _seekRange = qMakePair(minimum, maximum); }
+
+ qreal playbackRate() const { return _playbackRate; }
+ void setPlaybackRate(qreal rate) { if (rate != _playbackRate) emit playbackRateChanged(_playbackRate = rate); }
+
+ QMediaContent media() const { return _media; }
+ void setMedia(const QMediaContent &content, QIODevice *stream)
+ {
+ _stream = stream;
+ _media = content;
+ if (_state != QMediaPlayer::StoppedState) {
+ _mediaStatus = _media.isNull() ? QMediaPlayer::NoMedia : QMediaPlayer::LoadingMedia;
+ emit stateChanged(_state = QMediaPlayer::StoppedState);
+ emit mediaStatusChanged(_mediaStatus);
+ }
+ emit mediaChanged(_media = content);
+ }
+ QIODevice *mediaStream() const { return _stream; }
+
+ void play() { if (_isValid && !_media.isNull() && _state != QMediaPlayer::PlayingState) emit stateChanged(_state = QMediaPlayer::PlayingState); }
+ void pause() { if (_isValid && !_media.isNull() && _state != QMediaPlayer::PausedState) emit stateChanged(_state = QMediaPlayer::PausedState); }
+ void stop() { if (_state != QMediaPlayer::StoppedState) emit stateChanged(_state = QMediaPlayer::StoppedState); }
+
+ QMediaPlayer::State _state;
+ QMediaPlayer::MediaStatus _mediaStatus;
+ QMediaPlayer::Error _error;
+ qint64 _duration;
+ qint64 _position;
+ int _volume;
+ bool _muted;
+ int _bufferStatus;
+ bool _audioAvailable;
+ bool _videoAvailable;
+ bool _isSeekable;
+ QPair<qint64, qint64> _seekRange;
+ qreal _playbackRate;
+ QMediaContent _media;
+ QIODevice *_stream;
+ bool _isValid;
+ QString _errorString;
+};
+
+class MockVideoSurface : public QAbstractVideoSurface
+{
+public:
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ const QAbstractVideoBuffer::HandleType) const
+ {
+ return QList<QVideoFrame::PixelFormat>();
+ }
+
+ bool present(const QVideoFrame &) { return false; }
+};
+
+class MockVideoRendererControl : public QVideoRendererControl
+{
+public:
+ MockVideoRendererControl() : m_surface(0) {}
+
+ QAbstractVideoSurface *surface() const { return m_surface; }
+ void setSurface(QAbstractVideoSurface *surface) { m_surface = surface; }
+
+ QAbstractVideoSurface *m_surface;
+};
+
+class MockVideoWindowControl : public QVideoWindowControl
+{
+public:
+ WId winId() const { return 0; }
+ void setWinId(WId) {}
+ QRect displayRect() const { return QRect(); }
+ void setDisplayRect(const QRect &) {}
+ bool isFullScreen() const { return false; }
+ void setFullScreen(bool) {}
+ void repaint() {}
+ QSize nativeSize() const { return QSize(); }
+ Qt::AspectRatioMode aspectRatioMode() const { return Qt::KeepAspectRatio; }
+ void setAspectRatioMode(Qt::AspectRatioMode) {}
+ int brightness() const { return 0; }
+ void setBrightness(int) {}
+ int contrast() const { return 0; }
+ void setContrast(int) {}
+ int hue() const { return 0; }
+ void setHue(int) {}
+ int saturation() const { return 0; }
+ void setSaturation(int) {}
+};
+
+class MockStreamsControl : public QMediaStreamsControl
+{
+public:
+ MockStreamsControl(QObject *parent = 0) : QMediaStreamsControl(parent) {}
+
+ int streamCount() { return _streams.count(); }
+ void setStreamCount(int count) { _streams.resize(count); }
+
+ StreamType streamType(int index) { return _streams.at(index).type; }
+ void setStreamType(int index, StreamType type) { _streams[index].type = type; }
+
+ QVariant metaData(int index, QtMultimediaKit::MetaData key) {
+ return _streams.at(index).metaData.value(key); }
+ void setMetaData(int index, QtMultimediaKit::MetaData key, const QVariant &value) {
+ _streams[index].metaData.insert(key, value); }
+
+ bool isActive(int index) { return _streams.at(index).active; }
+ void setActive(int index, bool state) { _streams[index].active = state; }
+
+private:
+ struct Stream
+ {
+ Stream() : type(UnknownStream), active(false) {}
+ StreamType type;
+ QMap<QtMultimediaKit::MetaData, QVariant> metaData;
+ bool active;
+ };
+
+ QVector<Stream> _streams;
+};
+
+class MockNetworkAccessControl : public QMediaNetworkAccessControl
+{
+ friend class MockPlayerService;
+
+public:
+ MockNetworkAccessControl() {}
+ ~MockNetworkAccessControl() {}
+
+ void setConfigurations(const QList<QNetworkConfiguration> &configurations)
+ {
+ _configurations = configurations;
+ _current = QNetworkConfiguration();
+ }
+
+ QNetworkConfiguration currentConfiguration() const
+ {
+ return _current;
+ }
+
+private:
+ void setCurrentConfiguration(QNetworkConfiguration configuration)
+ {
+ if (_configurations.contains(configuration))
+ emit configurationChanged(_current = configuration);
+ else
+ emit configurationChanged(_current = QNetworkConfiguration());
+ }
+
+ QList<QNetworkConfiguration> _configurations;
+ QNetworkConfiguration _current;
+};
+
+Q_DECLARE_METATYPE(QNetworkConfiguration)
+
+class MockPlayerService : public QMediaService
+{
+ Q_OBJECT
+
+public:
+ MockPlayerService():QMediaService(0)
+ {
+ mockControl = new MockPlayerControl;
+ mockStreamsControl = new MockStreamsControl;
+ mockNetworkControl = new MockNetworkAccessControl;
+ rendererControl = new MockVideoRendererControl;
+ windowControl = new MockVideoWindowControl;
+ rendererRef = 0;
+ windowRef = 0;
+ }
+
+ ~MockPlayerService()
+ {
+ delete mockControl;
+ delete mockStreamsControl;
+ delete mockNetworkControl;
+ delete rendererControl;
+ delete windowControl;
+ }
+
+ QMediaControl* requestControl(const char *iid)
+ {
+ if (qstrcmp(iid, QMediaPlayerControl_iid) == 0) {
+ return mockControl;
+ } else if (qstrcmp(iid, QVideoRendererControl_iid) == 0) {
+ if (rendererRef == 0) {
+ rendererRef += 1;
+ return rendererControl;
+ }
+ } else if (qstrcmp(iid, QVideoWindowControl_iid) == 0) {
+ if (windowRef == 0) {
+ windowRef += 1;
+ return windowControl;
+ }
+ }
+
+
+ if (qstrcmp(iid, QMediaNetworkAccessControl_iid) == 0)
+ return mockNetworkControl;
+ return 0;
+ }
+
+ void releaseControl(QMediaControl *control)
+ {
+ if (control == rendererControl)
+ rendererRef -= 1;
+ else if (control == windowControl)
+ windowRef -= 1;
+ }
+
+ void setState(QMediaPlayer::State state) { emit mockControl->stateChanged(mockControl->_state = state); }
+ void setState(QMediaPlayer::State state, QMediaPlayer::MediaStatus status) {
+ mockControl->_state = state;
+ mockControl->_mediaStatus = status;
+ emit mockControl->mediaStatusChanged(status);
+ emit mockControl->stateChanged(state);
+ }
+ void setMediaStatus(QMediaPlayer::MediaStatus status) { emit mockControl->mediaStatusChanged(mockControl->_mediaStatus = status); }
+ void setIsValid(bool isValid) { mockControl->_isValid = isValid; }
+ void setMedia(QMediaContent media) { mockControl->_media = media; }
+ void setDuration(qint64 duration) { mockControl->_duration = duration; }
+ void setPosition(qint64 position) { mockControl->_position = position; }
+ void setSeekable(bool seekable) { mockControl->_isSeekable = seekable; }
+ void setVolume(int volume) { mockControl->_volume = volume; }
+ void setMuted(bool muted) { mockControl->_muted = muted; }
+ void setVideoAvailable(bool videoAvailable) { mockControl->_videoAvailable = videoAvailable; }
+ void setBufferStatus(int bufferStatus) { mockControl->_bufferStatus = bufferStatus; }
+ void setPlaybackRate(qreal playbackRate) { mockControl->_playbackRate = playbackRate; }
+ void setError(QMediaPlayer::Error error) { mockControl->_error = error; emit mockControl->error(mockControl->_error, mockControl->_errorString); }
+ void setErrorString(QString errorString) { mockControl->_errorString = errorString; emit mockControl->error(mockControl->_error, mockControl->_errorString); }
+
+ void selectCurrentConfiguration(QNetworkConfiguration config) { mockNetworkControl->setCurrentConfiguration(config); }
+
+ void reset()
+ {
+ mockControl->_state = QMediaPlayer::StoppedState;
+ mockControl->_mediaStatus = QMediaPlayer::UnknownMediaStatus;
+ mockControl->_error = QMediaPlayer::NoError;
+ mockControl->_duration = 0;
+ mockControl->_position = 0;
+ mockControl->_volume = 0;
+ mockControl->_muted = false;
+ mockControl->_bufferStatus = 0;
+ mockControl->_videoAvailable = false;
+ mockControl->_isSeekable = false;
+ mockControl->_playbackRate = 0.0;
+ mockControl->_media = QMediaContent();
+ mockControl->_stream = 0;
+ mockControl->_isValid = false;
+ mockControl->_errorString = QString();
+
+ mockNetworkControl->_current = QNetworkConfiguration();
+ mockNetworkControl->_configurations = QList<QNetworkConfiguration>();
+ }
+
+ MockPlayerControl *mockControl;
+ MockStreamsControl *mockStreamsControl;
+ MockNetworkAccessControl *mockNetworkControl;
+ MockVideoRendererControl *rendererControl;
+ MockVideoWindowControl *windowControl;
+ int rendererRef;
+ int windowRef;
+};
+
+class MockProvider : public QMediaServiceProvider
+{
+public:
+ MockProvider(MockPlayerService *service):mockService(service), deleteServiceOnRelease(true) {}
+ QMediaService *requestService(const QByteArray &, const QMediaServiceProviderHint &)
+ {
+ return mockService;
+ }
+
+ void releaseService(QMediaService *service) { if (deleteServiceOnRelease) delete service; }
+
+ MockPlayerService *mockService;
+ bool deleteServiceOnRelease;
+};
+
+class tst_QMediaPlayer: public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase_data();
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void testNullService();
+ void testValid();
+ void testMedia();
+ void testDuration();
+ void testPosition();
+ void testVolume();
+ void testMuted();
+ void testIsAvailable();
+ void testVideoAvailable();
+ void testBufferStatus();
+ void testSeekable();
+ void testPlaybackRate();
+ void testError();
+ void testErrorString();
+ void testService();
+ void testPlay();
+ void testPause();
+ void testStop();
+ void testMediaStatus();
+ void testPlaylist();
+ void testNetworkAccess();
+ void testSetVideoOutput();
+ void testSetVideoOutputNoService();
+ void testSetVideoOutputNoControl();
+ void testSetVideoOutputDestruction();
+ void testPositionPropertyWatch();
+ void debugEnums();
+
+private:
+ MockProvider *mockProvider;
+ MockPlayerService *mockService;
+ QMediaPlayer *player;
+};
+
+#endif //TST_QMEDIAPLAYER_H
diff --git a/tests/auto/qmediaplayer/tst_qmediaplayer_s60.cpp b/tests/auto/qmediaplayer/tst_qmediaplayer_s60.cpp
new file mode 100755
index 000000000..f30934a96
--- /dev/null
+++ b/tests/auto/qmediaplayer/tst_qmediaplayer_s60.cpp
@@ -0,0 +1,1708 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include "tst_qmediaplayer_s60.h"
+#include <qmediastreamscontrol.h>
+
+static const QString TestFilePath = QLatin1String("c:/data/testfiles/");
+
+// Comment out the following line if the test device does not have network
+// access.
+#define TEST_DEVICE_HAS_NETWORK_ACCESS
+
+QT_USE_NAMESPACE
+
+void tst_QMediaPlayer_s60::initTestCase_data()
+{
+#ifdef __WINSCW__
+ initTestCase_data_default_winscw();
+#else
+ initTestCase_data_default_armv5();
+#endif
+}
+
+void tst_QMediaPlayer_s60::initTestCase_data_default_armv5()
+{
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<bool>("streamable");
+ QTest::addColumn<QMediaPlayer::State>("state");
+ QTest::addColumn<QMediaPlayer::MediaStatus>("status");
+ QTest::addColumn<QMediaContent>("mediaContent");
+ QTest::addColumn<qint64>("duration");
+ QTest::addColumn<qint64>("position");
+ QTest::addColumn<bool>("seekable");
+ QTest::addColumn<bool>("seekableWhilePlaying");
+ QTest::addColumn<int>("volume");
+ QTest::addColumn<bool>("videoAvailable");
+ QTest::addColumn<bool>("audioAvailable");
+ QTest::addColumn<qreal>("playbackRate");
+ QTest::addColumn<QMediaPlayer::Error>("error");
+ QTest::addColumn<QString>("errorString");
+
+ QTest::newRow("TestDataNull")
+ << false //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::NoMedia // status
+ << QMediaContent() // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position
+ << false // seekable
+ << false // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_3gp.3gp")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status LoadedMedia
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_3gp.3gp")) // mediaContent
+ << qint64(46860) // duration
+ << qint64(23430) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << true //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_mp4.mp4")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_mp4.mp4")) // mediaContent
+ << qint64(2701) // duration
+ << qint64(1351) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << true //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_wmv9.wmv")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_wmv9.wmv")) // mediaContent
+ << qint64(169389) // duration
+ << qint64(84695) // position (duration/2)
+ << true // seekable
+ << false // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << true //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_AAC.dat")
+ << false //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::InvalidMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_AAC.dat")) // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::ResourceError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_amr.amr")
+ << true // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_amr.amr")) // mediaContent
+ << qint64(14400) // duration
+ << qint64(7200) // position
+ << true // seekable
+ << false // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << true // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_mp3.mp3")
+ << true // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_mp3.mp3")) // mediaContent
+ << qint64(102044) //qint64(102044) duration
+ << qint64(51022) // position
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << true // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+#ifdef TEST_DEVICE_HAS_NETWORK_ACCESS
+ QTest::newRow("test_stream 3gp")
+ << false // valid
+ << true //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl("rtsp://v3.cache4.c.youtube.com/CkgLENy73wIaPwlU2rm7yu8PFhMYESARFEIJbXYtZ29vZ2xlSARSB3JlbGF0ZWRaDkNsaWNrVGh1bWJuYWlsYPi6_IXT2rvpSgw=/0/0/0/video.3gp")) // mediaContent
+ << qint64(103000) // duration
+ << qint64(0) // position
+ << false // seekable
+ << false // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << true // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("RTSP link to H.263/AMR")
+ << false // valid
+ << true //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl("rtsp://v7.cache8.c.youtube.com/CiILENy73wIaGQnNUH6lxLd0MRMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp")) // mediaContent
+ << qint64(249000) // duration
+ << qint64(0) // position
+ << false // seekable
+ << false // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << true // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("RTSP link to MPEG-4/AAC")
+ << false // valid
+ << true //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl("rtsp://v8.cache1.c.youtube.com/CiILENy73wIaGQnNUH6lxLd0MRMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp")) // mediaContent
+ << qint64(249000) // duration
+ << qint64(0) // position
+ << false // seekable
+ << false // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << true // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+#endif // TEST_DEVICE_HAS_NETWORK_ACCESS
+}
+
+void tst_QMediaPlayer_s60::initTestCase_data_default_winscw()
+{
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<bool>("streamable");
+ QTest::addColumn<QMediaPlayer::State>("state");
+ QTest::addColumn<QMediaPlayer::MediaStatus>("status");
+ QTest::addColumn<QMediaContent>("mediaContent");
+ QTest::addColumn<qint64>("duration");
+ QTest::addColumn<qint64>("position");
+ QTest::addColumn<bool>("seekable");
+ QTest::addColumn<bool>("seekableWhilePlaying");
+ QTest::addColumn<int>("volume");
+ QTest::addColumn<bool>("videoAvailable");
+ QTest::addColumn<bool>("audioAvailable");
+ QTest::addColumn<qreal>("playbackRate");
+ QTest::addColumn<QMediaPlayer::Error>("error");
+ QTest::addColumn<QString>("errorString");
+
+ QTest::newRow("TestDataNull")
+ << false //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::NoMedia // status
+ << QMediaContent() // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position
+ << false // seekable
+ << false // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_3GPP.dat")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_3GPP.dat")) // mediaContent
+ << qint64(7200) // duration
+ << qint64(3600) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << true //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_3gp.3gp")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_3gp.3gp")) // mediaContent
+ << qint64(46860) // duration
+ << qint64(23430) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << true //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_mp4.mp4")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_mp4.mp4")) // mediaContent
+ << qint64(2701) // duration
+ << qint64(1351) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::FormatError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_MP4.dat")
+ << false //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::InvalidMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_MP4.dat")) // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::AccessDeniedError// error
+ << QString(); // errorString
+
+ QTest::newRow("test_wmv9.wmv")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_wmv9.wmv")) // mediaContent
+ << qint64(169389) // duration
+ << qint64(84695) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::FormatError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_h264_qcif.264")
+ << false //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::InvalidMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_h264_qcif.264")) // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::ResourceError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_RM.dat")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_RM.dat")) // mediaContent
+ << qint64(20245) // duration
+ << qint64(10123) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << true //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_SWF.dat")
+ << false //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::InvalidMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_SWF.dat")) // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::ResourceError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_WMV.dat")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_WMV.dat")) // mediaContent
+ << qint64(3098) // duration
+ << qint64(1549) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying, on emulator codec leaks memory and causes alloc panic on dtor
+ << 50 // volume
+ << true // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::FormatError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_WMA.dat")
+ << false //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::InvalidMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_WMA.dat")) // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::AccessDeniedError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_flash_video.flv")
+ << false // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::InvalidMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_flash_video.flv")) // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << false //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::ResourceError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_MXMF.dat")
+ << true //valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_MXMF.dat")) // mediaContent
+ << qint64(31980) // duration
+ << qint64(15990) // position (duration/2)
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << true //audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_amr.amr")
+ << true // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_amr.amr")) // mediaContent
+ << qint64(14402) // duration
+ << qint64(7200) // position
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << true // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_AMR.dat")
+ << true // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_AMR.dat")) // mediaContent
+ << qint64(38509) // duration
+ << qint64(19255) // position
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << true // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_mp3.mp3")
+ << false // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_mp3.mp3")) // mediaContent
+ << qint64(-1) //qint64(102044) duration
+ << qint64(0) // position
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << false // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::ResourceError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_MP3.dat")
+ << false // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::InvalidMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_MP3.dat")) // mediaContent
+ << qint64(-1) //qint64(102044) duration
+ << qint64(0) // position
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << false // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::ResourceError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_MIDI.dat")
+ << true // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_MIDI.dat")) // mediaContent
+ << qint64(32782) // duration
+ << qint64(16391) // position
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << true // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_ACC.dat")
+ << false // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::InvalidMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_ACC.dat")) // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << false // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::ResourceError // error
+ << QString(); // errorString
+
+ QTest::newRow("test_WAV.dat")
+ << true // valid
+ << false //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl::fromLocalFile(TestFilePath + "test_WAV.dat")) // mediaContent
+ << qint64(2864) // duration
+ << qint64(1432) // position
+ << true // seekable
+ << true // seekableWhilePlaying
+ << 50 // volume
+ << false // videoAvailable
+ << true // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::NoError // error
+ << QString(); // errorString
+
+#ifdef TEST_DEVICE_HAS_NETWORK_ACCESS
+ QTest::newRow("test_stream")
+ << false // valid
+ << true //streamable
+ << QMediaPlayer::StoppedState // state
+ << QMediaPlayer::LoadedMedia // status
+ << QMediaContent(QUrl("rtsp://v3.cache4.c.youtube.com/CkgLENy73wIaPwlU2rm7yu8PFhMYESARFEIJbXYtZ29vZ2xlSARSB3JlbGF0ZWRaDkNsaWNrVGh1bWJuYWlsYPi6_IXT2rvpSgw=/0/0/0/video.3gp")) // mediaContent
+ << qint64(-1) // duration
+ << qint64(0) // position
+ << false // seekable
+ << false // seekableWhilePlaying
+ << 50 // volume
+ << true // videoAvailable
+ << false // audioAvailable
+ << qreal(0) // playbackRate
+ << QMediaPlayer::AccessDeniedError // error
+ << QString(); // errorString
+#endif
+}
+
+void tst_QMediaPlayer_s60::initTestCase()
+{
+ m_player = new QMediaPlayer();
+
+ // Symbian back end needs coecontrol for creation.
+ m_widget = new QVideoWidget();
+ m_player->setVideoOutput(m_widget);
+ m_widget->show();
+ runonce = false;
+}
+
+void tst_QMediaPlayer_s60::cleanupTestCase()
+{
+ delete m_player;
+ delete m_widget;
+}
+
+void tst_QMediaPlayer_s60::init()
+{
+ qRegisterMetaType<QMediaPlayer::State>("QMediaPlayer::State");
+ qRegisterMetaType<QMediaPlayer::Error>("QMediaPlayer::Error");
+ qRegisterMetaType<QMediaPlayer::MediaStatus>("QMediaPlayer::MediaStatus");
+ qRegisterMetaType<QMediaContent>("QMediaContent");
+}
+
+void tst_QMediaPlayer_s60::cleanup()
+{
+}
+
+void tst_QMediaPlayer_s60::testNullService()
+{
+ if(runonce)
+ return;
+ MockProvider_s60 provider(0);
+ QMediaPlayer player(0, 0, &provider);
+
+ const QIODevice *nullDevice = 0;
+
+ QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(player.mediaStream(), nullDevice);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(player.duration(), qint64(-1));
+ QCOMPARE(player.position(), qint64(0));
+ QCOMPARE(player.volume(), 0);
+ QCOMPARE(player.isMuted(), false);
+ QCOMPARE(player.isVideoAvailable(), false);
+ QCOMPARE(player.bufferStatus(), 0);
+ QCOMPARE(player.isSeekable(), false);
+ QCOMPARE(player.playbackRate(), qreal(0));
+ QCOMPARE(player.error(), QMediaPlayer::ServiceMissingError);
+
+ {
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+
+ QSignalSpy spy(&player, SIGNAL(mediaChanged(QMediaContent)));
+ QFile file;
+
+ player.setMedia(mediaContent, &file);
+ QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(player.mediaStream(), nullDevice);
+ QCOMPARE(spy.count(), 0);
+ } {
+ QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+
+ player.play();
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+
+ player.pause();
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+
+ player.stop();
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+ } {
+ QFETCH_GLOBAL(int, volume);
+
+ QSignalSpy volumeSpy(&player, SIGNAL(volumeChanged(int)));
+ QSignalSpy mutingSpy(&player, SIGNAL(mutedChanged(bool)));
+
+ player.setVolume(volume);
+ QCOMPARE(player.volume(), 0);
+ QCOMPARE(volumeSpy.count(), 0);
+
+ player.setMuted(false);
+ QCOMPARE(player.isMuted(), false);
+ QCOMPARE(mutingSpy.count(), 0);
+ } {
+ QFETCH_GLOBAL(qint64, position);
+
+ QSignalSpy spy(&player, SIGNAL(positionChanged(qint64)));
+
+ player.setPosition(position);
+ QCOMPARE(player.position(), qint64(0));
+ QCOMPARE(spy.count(), 0);
+ } {
+ QFETCH_GLOBAL(qreal, playbackRate);
+
+ QSignalSpy spy(&player, SIGNAL(playbackRateChanged(qreal)));
+
+ player.setPlaybackRate(playbackRate);
+ QCOMPARE(player.playbackRate(), qreal(0));
+ QCOMPARE(spy.count(), 0);
+ } {
+ QMediaPlaylist playlist;
+ player.setPlaylist(&playlist);
+
+ QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(QMediaContent)));
+ QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+
+ playlist.addMedia(QUrl("http://example.com/stream"));
+ playlist.addMedia(QUrl("file:///some.mp3"));
+
+ playlist.setCurrentIndex(0);
+ QCOMPARE(playlist.currentIndex(), 0);
+ QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(mediaSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+
+ playlist.next();
+ QCOMPARE(playlist.currentIndex(), 1);
+ QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(mediaSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+ }
+ runonce = true;
+}
+
+void tst_QMediaPlayer_s60::testMedia()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ m_player->setMedia(mediaContent);
+ QTest::qWait(500);
+ QCOMPARE(m_player->media(), mediaContent);
+}
+
+
+void tst_QMediaPlayer_s60::testDuration()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(qint64, duration);
+ QFETCH_GLOBAL(bool, valid);
+
+ QSignalSpy spy(m_player, SIGNAL(durationChanged(qint64)));
+ m_player->setMedia(mediaContent);
+
+ if(valid) {
+ WAIT_FOR_CONDITION(spy.count(), 1);
+ } else {
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia));
+ }
+
+ QVERIFY(m_player->duration() == duration);
+}
+
+void tst_QMediaPlayer_s60::testPosition()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(qint64, duration);
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(bool, seekable);
+ QFETCH_GLOBAL(qint64, position);
+ QFETCH_GLOBAL(QMediaPlayer::MediaStatus, status);
+
+ m_player->setMedia(mediaContent);
+
+ if (valid) {
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ QCOMPARE(m_player->isSeekable(), seekable);
+ //QCOMPARE(m_player->mediaStatus(), status);
+ QVERIFY(m_player->mediaStatus() == status);
+
+ // preset position
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(position);
+ QCOMPARE(m_player->position(), position);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), position);}
+
+ // same pos second time
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(position);
+ QCOMPARE(m_player->position(), position);
+ QCOMPARE(spy.count(), 0);}
+
+ //zero pos
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(0);
+ QCOMPARE(m_player->position(), qint64(0));
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), qint64(0));}
+
+ //end pos
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(duration);
+ QCOMPARE(m_player->position(), duration);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), duration);}
+
+ //negative pos
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(qint64(-1));
+ QCOMPARE(m_player->position(), qint64(0));
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), qint64(0));}
+
+ //over duration
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(duration+1);
+ QCOMPARE(m_player->position(), duration);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), duration);}
+
+ } else {
+ if (valid)
+ WAIT_LONG_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia)
+ else
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia))
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->isSeekable(), seekable);
+ QCOMPARE(m_player->mediaStatus(), status);
+ }
+}
+
+void tst_QMediaPlayer_s60::testPositionWhilePlaying()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(qint64, duration);
+ QFETCH_GLOBAL(bool, seekableWhilePlaying);
+ QFETCH_GLOBAL(bool, seekable);
+ QFETCH_GLOBAL(qint64, position);
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(bool, streamable);
+ QFETCH_GLOBAL(QMediaPlayer::MediaStatus, status);
+
+ m_player->setMedia(mediaContent);
+
+ if (streamable) {
+ WAIT_LONG_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ } else {
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ }
+
+ //qDebug()<<"";
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->isSeekable(), seekable);
+ QCOMPARE(m_player->mediaStatus(), status);
+
+ if (seekableWhilePlaying && valid) {
+ QCOMPARE(m_player->isSeekable(), seekableWhilePlaying);
+
+ // preset position
+ //qDebug()<<"preset";
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ m_player->setPosition(position);
+ WAIT_FOR_CONDITION(spy.count(), 2);
+ QVERIFY(m_player->mediaStatus() == QMediaPlayer::BufferingMedia ||
+ m_player->mediaStatus() == QMediaPlayer::BufferedMedia ||
+ m_player->mediaStatus() == QMediaPlayer::EndOfMedia ||
+ m_player->mediaStatus() == QMediaPlayer::LoadedMedia);
+
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->position()>=position);
+ QVERIFY(spy.count()!=0);}
+
+ //reset position
+ m_player->stop();
+ m_player->setPosition(position);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ //zero pos
+ //qDebug()<<"zero";
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ m_player->setPosition(0);
+ WAIT_FOR_CONDITION(spy.count(), 2);
+ QVERIFY(m_player->mediaStatus() == QMediaPlayer::BufferingMedia ||
+ m_player->mediaStatus() == QMediaPlayer::BufferedMedia ||
+ m_player->mediaStatus() == QMediaPlayer::EndOfMedia ||
+ m_player->mediaStatus() == QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->position() >= qint64(0));
+ QVERIFY(spy.count()!=0);}
+
+ //reset position
+ m_player->stop();
+ m_player->setPosition(position);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ //end pos
+ //qDebug()<<"dur";
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ m_player->setPosition(duration);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->position(), qint64(0));
+ QVERIFY(spy.count()!=0);}
+
+ //reset position
+ m_player->stop();
+ m_player->setPosition(position);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ //negative pos
+ //qDebug()<<"negavite";
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ m_player->setPosition(qint64(-1));
+ WAIT_FOR_CONDITION(spy.count(), 2);
+ QVERIFY(m_player->mediaStatus() == QMediaPlayer::BufferingMedia ||
+ m_player->mediaStatus() == QMediaPlayer::BufferedMedia ||
+ m_player->mediaStatus() == QMediaPlayer::EndOfMedia ||
+ m_player->mediaStatus() == QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->position() >= qint64(0));
+ QVERIFY(spy.count()!=0);}
+
+ //reset position
+ m_player->stop();
+ m_player->setPosition(position);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ //over duration
+ //qDebug()<<"over";
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ m_player->setPosition(duration+1);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ // s60 MP3 controller has a weard feature to reduce position by ~200 when position
+ // is set over the duration, therefore we skip it here
+ if (!mediaContent.canonicalUrl().path().endsWith("mp3")) {
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->position(), qint64(0));
+ QVERIFY(spy.count()!=0);}
+ }
+ } else
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ //qDebug()<<"end";
+}
+
+
+void tst_QMediaPlayer_s60::testVolume()
+{
+ QFETCH_GLOBAL(int, volume);
+
+ // preset volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(volume);
+ QCOMPARE(m_player->volume(), volume);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+
+ // same volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ int currentVolume = m_player->volume();
+ m_player->setVolume(currentVolume);
+ QCOMPARE(m_player->volume(), currentVolume);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 0);}
+
+ // zero volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(0);
+ QCOMPARE(m_player->volume(), 0);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+
+ // max volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(100);
+ QCOMPARE(m_player->volume(), 100);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+
+ // negative volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(int(-1));
+ QCOMPARE(m_player->volume(), 0);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+
+ // over max volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(1000);
+ QCOMPARE(m_player->volume(), 100);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+}
+
+void tst_QMediaPlayer_s60::testVolumeWhilePlaying()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(int, volume);
+ QFETCH_GLOBAL(bool, valid);
+
+ if (valid) {
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ // preset volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(volume);
+ QCOMPARE(m_player->volume(), volume);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+
+ // same volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ int currentVolume = m_player->volume();
+ m_player->setVolume(currentVolume);
+ QCOMPARE(m_player->volume(), currentVolume);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 0);}
+
+ // zero volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(0);
+ QCOMPARE(m_player->volume(), 0);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+
+ // max volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(100);
+ QCOMPARE(m_player->volume(), 100);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+
+ // negative volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(int(-1));
+ QCOMPARE(m_player->volume(), 0);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+
+ // over max volume
+ { QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(1000);
+ QCOMPARE(m_player->volume(), 100);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);}
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ }
+}
+
+
+void tst_QMediaPlayer_s60::testMuted()
+{
+ QFETCH_GLOBAL(int, volume);
+
+ //reset mute & volume
+ m_player->setMuted(false);
+ m_player->setVolume(0);
+ QVERIFY(m_player->isMuted() == false);
+ QCOMPARE(m_player->volume(), 0);
+
+ // set muted
+ {QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(true);
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(m_player->isMuted() == true);}
+
+ // set muted again
+ {QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(true);
+ QCOMPARE(spy.count(), 0);
+ QVERIFY(m_player->isMuted() == true);}
+
+ // unmute
+ {QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(false);
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(m_player->isMuted() == false);}
+
+ // set volume while muted
+ {QSignalSpy muteSpy(m_player, SIGNAL(mutedChanged(bool)));
+ QSignalSpy volumeSpy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setMuted(true);
+ m_player->setVolume(volume);
+ QCOMPARE(m_player->volume(), volume);
+ QCOMPARE(muteSpy.count(), 1);
+ QCOMPARE(volumeSpy.count(), 1);
+ QVERIFY(m_player->isMuted() == true);}
+}
+
+void tst_QMediaPlayer_s60::testMutedWhilePlaying()
+{
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(int, volume);
+ QFETCH_GLOBAL(bool, valid);
+
+ if (valid) {
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ //reset mute & volume
+ m_player->setMuted(false);
+ m_player->setVolume(65);
+ QVERIFY(m_player->isMuted() == false);
+ QCOMPARE(m_player->volume(), 65);
+
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ // set muted
+ {QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(true);
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(m_player->isMuted() == true);}
+
+ // set muted again
+ {QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(true);
+ QCOMPARE(spy.count(), 0);
+ QVERIFY(m_player->isMuted() == true);}
+
+ // unmute
+ {QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(false);
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(m_player->isMuted() == false);}
+
+ // set volume while muted
+ {QSignalSpy muteSpy(m_player, SIGNAL(mutedChanged(bool)));
+ QSignalSpy volumeSpy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setMuted(true);
+ m_player->setVolume(volume);
+ QCOMPARE(m_player->volume(), volume);
+ QCOMPARE(muteSpy.count(), 1);
+ QCOMPARE(volumeSpy.count(), 1);
+ QVERIFY(m_player->isMuted() == true);}
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ }
+}
+
+
+void tst_QMediaPlayer_s60::testVideoAndAudioAvailability()
+{
+ QFETCH_GLOBAL(bool, videoAvailable);
+ QFETCH_GLOBAL(bool, audioAvailable);
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+
+ if(valid) {
+ QSignalSpy audioAvailableSpy(m_player, SIGNAL(audioAvailableChanged(bool)));
+ QSignalSpy videoAvailableSpy(m_player, SIGNAL(videoAvailableChanged(bool)));
+
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ QVERIFY(m_player->isVideoAvailable() == videoAvailable);
+ QVERIFY(m_player->isAudioAvailable() == audioAvailable);
+
+ QCOMPARE(audioAvailableSpy.count(), 1);
+ QCOMPARE(videoAvailableSpy.count(), 1);
+ }
+}
+
+void tst_QMediaPlayer_s60::testError()
+{
+ QFETCH_GLOBAL(QMediaPlayer::Error, error);
+ QFETCH_GLOBAL(bool, videoAvailable);
+ QFETCH_GLOBAL(bool, audioAvailable);
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(QMediaPlayer::State, state);
+ QFETCH_GLOBAL(QMediaPlayer::MediaStatus, status);
+
+ QSignalSpy errorSpy(m_player, SIGNAL(error(QMediaPlayer::Error)));
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ QVERIFY(m_player->mediaStatus() == status);
+ QVERIFY(m_player->state() == state);
+ QVERIFY(m_player->error() == error);
+ if (error != QMediaPlayer::NoError) {
+ QVERIFY(errorSpy.count()!=0);
+ }
+}
+
+void tst_QMediaPlayer_s60::testPlay()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(bool, streamable);
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(QMediaPlayer::State, state);
+
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ QVERIFY(m_player->state() == state);
+ QVERIFY(m_player->media() == mediaContent);
+ QSignalSpy spy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->play();
+
+ if(valid) {
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(spy.count(), state == QMediaPlayer::PlayingState ? 0 : 1);
+
+ //Play->Play
+ {QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 0);}
+
+ //Play->Pause
+ {QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->pause();
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(stateSpy.count(), 1);}
+
+ //Play->Stop
+ {m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ if (m_player->mediaStatus() != QMediaPlayer::EndOfMedia) {
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 1);
+ } else {
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 4);
+ }}
+ } else if (streamable) {
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 2);
+ } else {
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+}
+
+void tst_QMediaPlayer_s60::testPause()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(bool, streamable);
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(QMediaPlayer::State, state);
+
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ QVERIFY(m_player->state() == state);
+ QVERIFY(m_player->media() == mediaContent);
+ QSignalSpy spy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->pause();
+
+ if(valid) {
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(spy.count(), 1);
+
+ //Pause->Play
+ {QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 1);}
+
+ //Pause->Pause
+ {m_player->pause();
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->pause();
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(stateSpy.count(), 0);}
+
+ //Pause->Stop
+ {QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 1);}
+ } else if (streamable) {
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 2);
+ } else {
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 0);
+ }
+}
+
+void tst_QMediaPlayer_s60::testStop()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(QMediaPlayer::State, state);
+
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ QVERIFY(m_player->state() == state);
+ QVERIFY(m_player->media() == mediaContent);
+
+ QSignalSpy spy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->stop();
+
+ if(valid) {
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 0);
+
+ //Stop->Play
+ {QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 1);}
+
+ //Stop->Pause
+ {m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->pause();
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(stateSpy.count(), 1);}
+
+ //Stop->Stop
+ {m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);}
+ } else {
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 0);
+ }
+}
+
+void tst_QMediaPlayer_s60::testMediaStatus()
+{
+ QFETCH_GLOBAL(bool, videoAvailable);
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(bool, streamable);
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+
+ QSignalSpy statusSpy(m_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ mediaStatusList list(m_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+
+ if(valid) {
+ if (videoAvailable) {
+ QCOMPARE(statusSpy.count(), 3);
+ QCOMPARE(list.count(), 3);
+ QCOMPARE(list.at(0), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(list.at(1), QMediaPlayer::LoadingMedia);
+ QCOMPARE(list.at(2), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ m_player->play();
+ {WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);}
+ QCOMPARE(statusSpy.count(), 5);
+ QCOMPARE(list.count(), 5);
+ QCOMPARE(list.at(3), QMediaPlayer::BufferingMedia);
+ QCOMPARE(list.at(4), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ {WAIT_LONG_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);}
+ QVERIFY(statusSpy.count() == 6);
+ QVERIFY(list.count() == 6);
+ QCOMPARE(list.last(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ }else {
+ QCOMPARE(statusSpy.count(), 3);
+ QCOMPARE(list.count(), 3);
+ QCOMPARE(list.at(0), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(list.at(1), QMediaPlayer::LoadingMedia);
+ QCOMPARE(list.at(2), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ m_player->play();
+ {WAIT_LONG_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);}
+ QVERIFY(statusSpy.count() == 4);
+ QVERIFY(list.count() == 4);
+ QCOMPARE(list.last(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ }
+ } else if (mediaContent.isNull()) {
+ QCOMPARE(statusSpy.count(), 2);
+ QCOMPARE(list.count(), 2);
+ QCOMPARE(list.at(0), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(list.at(1), QMediaPlayer::NoMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::NoMedia);
+ m_player->play();
+ QCOMPARE(statusSpy.count(), 2);
+ QCOMPARE(list.count(), 2);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::NoMedia);
+ } else if (streamable) {
+ QCOMPARE(statusSpy.count(), 3);
+ QCOMPARE(list.count(), 3);
+ QCOMPARE(list.at(0), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(list.at(1), QMediaPlayer::LoadingMedia);
+ QCOMPARE(list.at(2), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ m_player->play();
+ QCOMPARE(statusSpy.count(), 3);
+ QCOMPARE(list.count(), 3);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ } else {
+ QCOMPARE(statusSpy.count(), 3);
+ QCOMPARE(list.count(), 3);
+ QCOMPARE(list.at(0), QMediaPlayer::UnknownMediaStatus);
+ QCOMPARE(list.at(1), QMediaPlayer::LoadingMedia);
+ QCOMPARE(list.at(2), QMediaPlayer::InvalidMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::InvalidMedia);
+ m_player->play();
+ QCOMPARE(statusSpy.count(), 3);
+ QCOMPARE(list.count(), 3);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::InvalidMedia);
+ }
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+}
+
+void tst_QMediaPlayer_s60::testPlaylist()
+{
+ if(!runonce) {
+ QMediaContent content0(QUrl::fromLocalFile(TestFilePath + "test_mp4.mp4"));
+ QMediaContent content1(QUrl::fromLocalFile(TestFilePath + "test_WAV.dat"));
+ QMediaContent content2(QUrl::fromLocalFile(TestFilePath + "test_mp4.mp4"));
+ QMediaContent content3(QUrl::fromLocalFile(TestFilePath + "test_WAV.dat"));
+ QMediaContent content4(QUrl::fromLocalFile(TestFilePath + "test_MIDI.dat"));
+
+ QMediaPlaylist *playlist = new QMediaPlaylist(m_player);
+ m_player->setPlaylist(playlist);
+
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ QSignalSpy mediaSpy(m_player, SIGNAL(mediaChanged(QMediaContent)));
+
+ // Test the player does nothing with an empty playlist attached.
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->media(), QMediaContent());
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(mediaSpy.count(), 0);
+
+ playlist->addMedia(content0);
+ playlist->addMedia(content1);
+ playlist->addMedia(content2);
+ playlist->addMedia(content3);
+
+ // Test changing the playlist position, changes the current media, but not the playing state.
+ playlist->setCurrentIndex(1);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->media(), content1);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(stateSpy.count(), 0);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ // Test playing starts with the current media.
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->media(), content1);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->mediaStatus() == (QMediaPlayer::BufferedMedia||QMediaPlayer::BufferingMedia));
+ QCOMPARE(stateSpy.count(), 1);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ // Test pausing doesn't change the current media.
+ m_player->pause();
+ QCOMPARE(m_player->media(), content1);
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QVERIFY(m_player->mediaStatus() == (QMediaPlayer::BufferedMedia||QMediaPlayer::BufferingMedia));
+ QCOMPARE(stateSpy.count(), 2);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ // Test stopping doesn't change the current media.
+ m_player->stop();
+ QCOMPARE(m_player->media(), content1);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(stateSpy.count(), 3);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ // Test when the player service reaches the end of the current media, the player moves onto
+ // the next item without stopping.
+ m_player->play();
+ QCOMPARE(m_player->media(), content1);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 4);
+ QCOMPARE(mediaSpy.count(), 1);
+
+ WAIT_FOR_CONDITION(mediaSpy.count(), 2);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->media(), content2);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->mediaStatus() == (QMediaPlayer::BufferedMedia||QMediaPlayer::BufferingMedia));
+ QCOMPARE(stateSpy.count(), 6);
+ QCOMPARE(mediaSpy.count(), 2);
+
+ // Test skipping the current media doesn't change the state.
+ playlist->next();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->media(), content3);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->mediaStatus() == (QMediaPlayer::BufferedMedia||QMediaPlayer::BufferingMedia));
+ QCOMPARE(stateSpy.count(), 6);
+ QCOMPARE(mediaSpy.count(), 3);
+
+ // Test changing the current media while paused doesn't change the state.
+ m_player->pause();
+ QCOMPARE(m_player->media(), content3);
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QVERIFY(m_player->mediaStatus() == (QMediaPlayer::BufferedMedia||QMediaPlayer::BufferingMedia));
+ QCOMPARE(stateSpy.count(), 7);
+ QCOMPARE(mediaSpy.count(), 3);
+
+ playlist->previous();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->media(), content2);
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QVERIFY(m_player->mediaStatus() == (QMediaPlayer::BufferedMedia||QMediaPlayer::BufferingMedia));
+ QCOMPARE(stateSpy.count(), 7);
+ QCOMPARE(mediaSpy.count(), 4);
+
+ // Test changing the current media while stopped doesn't change the state.
+ m_player->stop();
+ QCOMPARE(m_player->media(), content2);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(stateSpy.count(), 8);
+ QCOMPARE(mediaSpy.count(), 4);
+
+ playlist->next();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->media(), content3);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(stateSpy.count(), 8);
+ QCOMPARE(mediaSpy.count(), 5);
+
+ // Test the player is stopped and the current media cleared when it reaches the end of the last
+ // item in the playlist.
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->media(), content3);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->mediaStatus() == (QMediaPlayer::BufferedMedia||QMediaPlayer::BufferingMedia));
+ QCOMPARE(stateSpy.count(), 9);
+ QCOMPARE(mediaSpy.count(), 5);
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(m_player->media(), QMediaContent());
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::NoMedia);
+ QCOMPARE(stateSpy.count(), 10);
+ QCOMPARE(mediaSpy.count(), 6);
+
+ // Test starts playing from the start of the playlist if there is no current media selected.
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->media(), content0);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->mediaStatus() == (QMediaPlayer::BufferedMedia||QMediaPlayer::BufferingMedia));
+ QCOMPARE(stateSpy.count(), 11);
+ QCOMPARE(mediaSpy.count(), 7);
+
+ // Test deleting the playlist stops the player and clears the media it set.
+ delete playlist;
+ QCOMPARE(m_player->media(), QMediaContent());
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::NoMedia);
+ QCOMPARE(stateSpy.count(), 12);
+ QCOMPARE(mediaSpy.count(), 8);
+
+ // Test the player works as normal with the playlist removed.
+ m_player->play();
+ QCOMPARE(m_player->media(), QMediaContent());
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::NoMedia);
+ QCOMPARE(stateSpy.count(), 12);
+ QCOMPARE(mediaSpy.count(), 8);
+
+ m_player->setMedia(content1);
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia)
+ QCOMPARE(m_player->media(), content1);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->mediaStatus() == (QMediaPlayer::BufferedMedia||QMediaPlayer::BufferingMedia));
+ QCOMPARE(stateSpy.count(), 13);
+ QCOMPARE(mediaSpy.count(), 9);
+ m_player->stop();
+ runonce = true;
+ }
+}
+
+void tst_QMediaPlayer_s60::testStreamControl()
+{
+ QFETCH_GLOBAL(bool, valid);
+ QFETCH_GLOBAL(bool, streamable);
+ QFETCH_GLOBAL(QMediaContent, mediaContent);
+ QFETCH_GLOBAL(QMediaPlayer::State, state);
+ QFETCH_GLOBAL(bool, videoAvailable);
+ QFETCH_GLOBAL(bool, audioAvailable);
+
+ QMediaStreamsControl* m_streamControl = (QMediaStreamsControl*)(m_player->service()->requestControl(QMediaStreamsControl_iid));
+ if(m_streamControl) {
+ if (valid || streamable) {
+ if (audioAvailable && !videoAvailable) {
+ QSignalSpy streamInfoSpy(m_streamControl, SIGNAL(streamsChanged()));
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ QVERIFY(m_streamControl->streamCount() == 1);
+ QVERIFY(m_streamControl->streamType(1) == QMediaStreamsControl::AudioStream);
+ QVERIFY(m_streamControl->isActive(1) == true);
+ QCOMPARE(streamInfoSpy.count(), 1);
+ }else if (audioAvailable && videoAvailable){
+ QSignalSpy streamInfoSpy(m_streamControl, SIGNAL(streamsChanged()));
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ QVERIFY(m_streamControl->streamCount() == 2);
+ QVERIFY(m_streamControl->streamType(1) == QMediaStreamsControl::VideoStream);
+ QVERIFY(m_streamControl->isActive(2) == true);
+ QCOMPARE(streamInfoSpy.count(), 1);
+ }else if (!audioAvailable && videoAvailable) {
+ QSignalSpy streamInfoSpy(m_streamControl, SIGNAL(streamsChanged()));
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ QVERIFY(m_streamControl->streamCount() == 1);
+ QVERIFY(m_streamControl->streamType(1) == QMediaStreamsControl::VideoStream);
+ QVERIFY(m_streamControl->isActive(2) == true);
+ QCOMPARE(streamInfoSpy.count(), 1);
+ }
+
+ // Test that streamsChanged signal do not get emitted when adding same media
+ QSignalSpy streamInfoSpy(m_streamControl, SIGNAL(streamsChanged()));
+ m_player->setMedia(mediaContent);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), (QMediaPlayer::NoMedia || QMediaPlayer::InvalidMedia || QMediaPlayer::LoadedMedia));
+ QCOMPARE(streamInfoSpy.count(), 0);
+ }
+ }
+}
diff --git a/tests/auto/qmediaplayer/tst_qmediaplayer_s60.h b/tests/auto/qmediaplayer/tst_qmediaplayer_s60.h
new file mode 100755
index 000000000..1ebe42588
--- /dev/null
+++ b/tests/auto/qmediaplayer/tst_qmediaplayer_s60.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef TST_QMEDIAPLAYER_S60_H
+#define TST_QMEDIAPLAYER_S60_H
+
+#include <QtTest/QtTest>
+#include <QtCore>
+#include <QtGui>
+#include <QFile>
+
+#include <QMediaPlayer>
+#include <QMediaPlayerControl>
+#include <QMediaPlaylist>
+#include <QMediaService>
+#include <QMediaStreamsControl>
+#include <QVideoWidget>
+
+QT_USE_NAMESPACE
+
+#define WAIT_FOR_CONDITION(a,e) \
+ for (int _i = 0; _i < 500; _i += 1) { \
+ if ((a) == (e)) break; \
+ QTest::qWait(10);}
+
+
+#define WAIT_LONG_FOR_CONDITION(a,e) \
+ for (int _i = 0; _i < 1800; _i += 1) { \
+ if ((a) == (e)) break; \
+ QTest::qWait(100);}
+
+class mediaStatusList : public QObject, public QList<QMediaPlayer::MediaStatus>
+{
+ Q_OBJECT
+public slots:
+ void mediaStatus(QMediaPlayer::MediaStatus status) {
+ append(status);
+ }
+
+public:
+ mediaStatusList(QObject *obj, const char *aSignal)
+ : QObject()
+ {
+ connect(obj, aSignal, this, SLOT(mediaStatus(QMediaPlayer::MediaStatus)));
+ }
+};
+
+class MockProvider_s60 : public QMediaServiceProvider
+{
+public:
+ MockProvider_s60(QMediaService *service):mockService(service) {}
+ QMediaService *requestService(const QByteArray &, const QMediaServiceProviderHint &)
+ {
+ return mockService;
+ }
+
+ void releaseService(QMediaService *service) { delete service; }
+
+ QMediaService *mockService;
+};
+
+class tst_QMediaPlayer_s60: public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase_data();
+ void initTestCase_data_default_winscw();
+ void initTestCase_data_default_armv5();
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void testNullService();
+ void testMedia();
+ void testDuration();
+ void testPosition();
+ void testPositionWhilePlaying();
+ void testVolume();
+ void testVolumeWhilePlaying();
+ void testMuted();
+ void testMutedWhilePlaying();
+ void testVideoAndAudioAvailability();
+ void testError();
+ void testPlay();
+ void testPause();
+ void testStop();
+ void testMediaStatus();
+ void testPlaylist();
+ void testStreamControl();
+
+private:
+ QMediaPlayer *m_player;
+ QVideoWidget *m_widget;
+ bool runonce;
+};
+
+#endif // TST_QMEDIAPLAYER_S60_H
diff --git a/tests/auto/qmediaplayer/tst_qmediaplayer_xa.cpp b/tests/auto/qmediaplayer/tst_qmediaplayer_xa.cpp
new file mode 100644
index 000000000..403fe5457
--- /dev/null
+++ b/tests/auto/qmediaplayer/tst_qmediaplayer_xa.cpp
@@ -0,0 +1,1413 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tst_QMediaPlayer_xa.h"
+
+QT_USE_NAMESPACE
+
+#define QTEST_MAIN_XA(TestObject) \
+ int main(int argc, char *argv[]) { \
+ char *new_argv[3]; \
+ QApplication app(argc, argv); \
+ \
+ QString str = "C:\\data\\" + QFileInfo(QCoreApplication::applicationFilePath()).baseName() + ".log"; \
+ QByteArray bytes = str.toAscii(); \
+ \
+ char arg1[] = "-o"; \
+ \
+ new_argv[0] = argv[0]; \
+ new_argv[1] = arg1; \
+ new_argv[2] = bytes.data(); \
+ \
+ TestObject tc; \
+ return QTest::qExec(&tc, 3, new_argv); \
+ }
+
+#define WAIT_FOR_CONDITION(a,e) \
+ for (int _i = 0; _i < 500; _i += 1) { \
+ if ((a) == (e)) break; \
+ QTest::qWait(10);}
+
+#define WAIT_FOR_EITHER_CONDITION(a,e,f) \
+ for (int _i = 0; _i < 500; _i += 1) { \
+ if (((a) == (e)) || ((a) == (f))) break; \
+ QTest::qWait(10);}
+
+#define WAIT_FOR_CONDITION1(a) \
+ for (int _i = 0; _i < 500; _i += 1) { \
+ if (a) break; \
+ QTest::qWait(10);}
+
+
+#define WAIT_LONG_FOR_CONDITION(a,e) \
+ for (int _i = 0; _i < 1800; _i += 1) { \
+ if ((a) == (e)) break; \
+ QTest::qWait(10);}
+
+#define WAIT_LONG_FOR_CONDITION1(a) \
+ for (int _i = 0; _i < 1800; _i += 1) { \
+ if (a) break; \
+ QTest::qWait(100);}
+
+tst_QMediaPlayer_xa::tst_QMediaPlayer_xa(): m_player(NULL), m_widget(NULL), m_windowWidget(NULL)
+{
+ audioOnlyContent = new QMediaContent(QUrl("file:///C:/data/testfiles/test.mp3"));
+ videoOnlyContent = new QMediaContent(QUrl("file:///C:/data/testfiles/test_video.3gp"));
+ audioVideoContent = new QMediaContent(QUrl("file:///C:/data/testfiles/test.3gp"));
+ audioVideoAltContent = new QMediaContent(QUrl("file:///C:/data/testfiles/test_alt.3gp"));
+ //streamingContent = new QMediaContent(QUrl("rtsp://10.48.2.51/Copyright_Free_Test_Content/Clips/Video/3GP/176x144/h263/h263_176x144_15fps_384kbps_AAC-LC_128kbps_mono_44.1kHz.3gp"));
+ streamingContent3gp = new QMediaContent(QUrl("http://www.mobileplayground.co.uk/video/Crazy Frog.3gp"));
+ audioStreamingContent = new QMediaContent(QUrl("http://myopusradio.com:8000/easy"));
+ mediaContent = audioVideoContent;
+}
+
+tst_QMediaPlayer_xa::~tst_QMediaPlayer_xa()
+{
+ delete audioOnlyContent;
+ delete videoOnlyContent;
+ delete audioVideoContent;
+ delete audioVideoAltContent;
+}
+
+void tst_QMediaPlayer_xa::initTestCase_data()
+{
+}
+
+void tst_QMediaPlayer_xa::initTestCase()
+{
+ m_player = new QMediaPlayer();
+
+ // Symbian back end needs coecontrol for creation.
+ m_widget = new QVideoWidget();
+ m_widget->setGeometry ( 0, 100, 350, 250 );
+ m_player->setVideoOutput(m_widget);
+ m_widget->showNormal();
+}
+
+void tst_QMediaPlayer_xa::cleanupTestCase()
+{
+ delete m_player;
+ delete m_widget;
+ delete m_windowWidget;
+}
+
+void tst_QMediaPlayer_xa::resetPlayer()
+{
+ delete m_player;
+ m_player = new QMediaPlayer();
+ m_player->setVideoOutput(m_widget);
+}
+
+void tst_QMediaPlayer_xa::resetPlayer_WindowControl()
+{
+ delete m_player;
+ m_player = new QMediaPlayer();
+
+ if(!m_windowWidget) {
+ m_windowWidget = new QWidget();
+ m_windowWidget->showMaximized();
+ }
+
+ QVideoWindowControl* windowControl = (QVideoWindowControl*)(m_player->service()->requestControl(QVideoWindowControl_iid));
+ if (windowControl)
+ windowControl->setWinId(m_windowWidget->winId());
+}
+
+void tst_QMediaPlayer_xa::init()
+{
+ qRegisterMetaType<QMediaPlayer::State>("QMediaPlayer::State");
+ qRegisterMetaType<QMediaPlayer::Error>("QMediaPlayer::Error");
+ qRegisterMetaType<QMediaPlayer::MediaStatus>("QMediaPlayer::MediaStatus");
+ qRegisterMetaType<QMediaContent>("QMediaContent");
+ updateLog("QT MediaPlayer Auto Test Cases", true);
+}
+
+void tst_QMediaPlayer_xa::cleanup()
+{
+}
+
+
+void tst_QMediaPlayer_xa::testMedia()
+{
+ updateLog("*****testMedia");
+
+ setAudioVideoContent();
+
+ QTest::qWait(500);
+ QCOMPARE(m_player->media(), *mediaContent);
+
+ updateLog("*****testMedia: PASSED");
+}
+
+
+void tst_QMediaPlayer_xa::testDuration()
+{
+ updateLog("*****testDuration");
+
+ resetPlayer();
+
+ QSignalSpy spy(m_player, SIGNAL(durationChanged(qint64)));
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION1(spy.count()>0);
+
+ QVERIFY(m_player->duration() == duration);
+
+ updateLog("*****testDuration: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testPosition()
+{
+ updateLog("*****testPosition");
+ resetPlayer();
+
+ qint64 position = 60000;
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ QCOMPARE(m_player->isSeekable(), true);
+
+ // preset position
+ {
+ QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(position);
+ WAIT_FOR_CONDITION(spy.count(), 1);
+ QCOMPARE(m_player->position(), position);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), position);
+ }
+
+ // same pos second time
+ {
+ QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(position);
+ QCOMPARE(m_player->position(), position);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ //zero pos
+ {
+ QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(0);
+ QCOMPARE(m_player->position(), qint64(0));
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), qint64(0));
+ }
+
+ //end pos
+ {
+ QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(duration);
+ QCOMPARE(m_player->position(), duration);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), duration);
+ }
+
+ //negative pos
+ {
+ QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(qint64(-1));
+ QCOMPARE(m_player->position(), qint64(0));
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), qint64(0));
+ }
+
+ //over duration
+ {
+ QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->setPosition(duration+1);
+ QCOMPARE(m_player->position(), duration);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toLongLong(), duration);
+ }
+
+}
+
+
+void tst_QMediaPlayer_xa::testPositionWhilePlaying()
+{
+ updateLog("*****testPositionWhilePlaying");
+ resetPlayer();
+
+ qint64 position = 60000;
+
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ // preset position
+ {
+ QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ m_player->setPosition(position);
+ WAIT_FOR_CONDITION1(spy.count()>0);
+ QVERIFY(m_player->mediaStatus() == QMediaPlayer::BufferingMedia || m_player->mediaStatus() == QMediaPlayer::BufferedMedia);
+
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->position()>=position);
+ QVERIFY(spy.count()!=0);
+ }
+
+ //reset position
+ m_player->stop();
+ m_player->setPosition(position);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ //zero pos
+ { QSignalSpy spy(m_player, SIGNAL(positionChanged(qint64)));
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ m_player->setPosition(0);
+ WAIT_FOR_CONDITION1(spy.count()>0);
+ QVERIFY(m_player->mediaStatus() == QMediaPlayer::BufferingMedia ||
+ m_player->mediaStatus() == QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QVERIFY(m_player->position() >= qint64(0));
+ QVERIFY(spy.count()!=0);
+ }
+
+ //reset position
+ m_player->stop();
+ m_player->setPosition(position);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ updateLog("*****testPositionWhilePlaying: PASSED");
+}
+
+
+void tst_QMediaPlayer_xa::testVolume()
+{
+ updateLog("*****testVolume");
+
+ int volume = 20;
+
+ // preset volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(volume);
+ QCOMPARE(m_player->volume(), volume);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ // same volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ int currentVolume = m_player->volume();
+ m_player->setVolume(currentVolume);
+ QCOMPARE(m_player->volume(), currentVolume);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ // zero volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(0);
+ QCOMPARE(m_player->volume(), 0);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ // max volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(100);
+ QCOMPARE(m_player->volume(), 100);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ // negative volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(int(-1));
+ QCOMPARE(m_player->volume(), 0);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ // over max volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(1000);
+ QCOMPARE(m_player->volume(), 100);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ updateLog("*****testVolume: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testVolumeWhilePlaying()
+{
+ updateLog("*****testVideoAndAudioAvailability");
+ resetPlayer();
+
+ int volume = 20;
+
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ // preset volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(volume);
+ QCOMPARE(m_player->volume(), volume);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ // same volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ int currentVolume = m_player->volume();
+ m_player->setVolume(currentVolume);
+ QCOMPARE(m_player->volume(), currentVolume);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ // zero volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(0);
+ QCOMPARE(m_player->volume(), 0);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ // max volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(100);
+ QCOMPARE(m_player->volume(), 100);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ // negative volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(int(-1));
+ QCOMPARE(m_player->volume(), 0);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ // over max volume
+ {
+ QSignalSpy spy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setVolume(1000);
+ QCOMPARE(m_player->volume(), 100);
+ QCOMPARE(m_player->isMuted(), false);
+ QCOMPARE(spy.count(), 1);
+ }
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ updateLog("*****testVideoAndAudioAvailability: PASSED");
+}
+
+
+void tst_QMediaPlayer_xa::testMuted()
+{
+ updateLog("*****testMuted");
+
+ int volume = 20;
+
+ //reset mute & volume
+ m_player->setMuted(false);
+ m_player->setVolume(0);
+ QVERIFY(m_player->isMuted() == false);
+ QCOMPARE(m_player->volume(), 0);
+
+ // set muted
+ {
+ QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(true);
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(m_player->isMuted() == true);
+ }
+
+ // set muted again
+ {
+ QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(true);
+ QCOMPARE(spy.count(), 0);
+ QVERIFY(m_player->isMuted() == true);
+ }
+
+ // unmute
+ {
+ QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(false);
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(m_player->isMuted() == false);
+ }
+
+ // set volume while muted
+ {
+ QSignalSpy muteSpy(m_player, SIGNAL(mutedChanged(bool)));
+ QSignalSpy volumeSpy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setMuted(true);
+ m_player->setVolume(volume);
+ QCOMPARE(m_player->volume(), volume);
+ QCOMPARE(muteSpy.count(), 1);
+ QCOMPARE(volumeSpy.count(), 1);
+ QVERIFY(m_player->isMuted() == true);
+ }
+
+ updateLog("*****testMuted: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testMutedWhilePlaying()
+{
+ updateLog("*****testMutedWhilePlaying");
+ resetPlayer();
+
+ int volume = 20;
+
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ //reset mute & volume
+ m_player->setMuted(false);
+ m_player->setVolume(65);
+ QVERIFY(m_player->isMuted() == false);
+ QCOMPARE(m_player->volume(), 65);
+
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ // set muted
+ {
+ QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(true);
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(m_player->isMuted() == true);
+ }
+
+ // set muted again
+ {
+ QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(true);
+ QCOMPARE(spy.count(), 0);
+ QVERIFY(m_player->isMuted() == true);
+ }
+
+ // unmute
+ {
+ QSignalSpy spy(m_player, SIGNAL(mutedChanged(bool)));
+ m_player->setMuted(false);
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(m_player->isMuted() == false);
+ }
+
+ // set volume while muted
+ {
+ QSignalSpy muteSpy(m_player, SIGNAL(mutedChanged(bool)));
+ QSignalSpy volumeSpy(m_player, SIGNAL(volumeChanged(int)));
+ m_player->setMuted(true);
+ m_player->setVolume(volume);
+ QCOMPARE(m_player->volume(), volume);
+ QCOMPARE(muteSpy.count(), 1);
+ QCOMPARE(volumeSpy.count(), 1);
+ QVERIFY(m_player->isMuted() == true);
+ }
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+
+ updateLog("*****testMutedWhilePlaying: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testVideoAndAudioAvailability()
+{
+ updateLog("*****testVideoAndAudioAvailability");
+ resetPlayer();
+
+ QList<QVariant> arguments;
+
+
+ setVideoOnlyContent();
+
+
+ QSignalSpy audioAvailableSpy(m_player, SIGNAL(audioAvailableChanged(bool)));
+ QSignalSpy videoAvailableSpy(m_player, SIGNAL(videoAvailableChanged(bool)));
+
+ setAudioOnlyContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ updateLog("SetMedia: audioOnlyContent");
+ WAIT_FOR_CONDITION(m_player->isAudioAvailable(), true);
+ updateLog("\t isAudioAvailable() == true");
+ QVERIFY(m_player->isVideoAvailable() == false);
+ updateLog("\t isVideoAvailable() == false");
+ QCOMPARE(audioAvailableSpy.count(), 1);
+ arguments = audioAvailableSpy.takeFirst();
+ QVERIFY(arguments.at(0).toBool() == true);
+ updateLog("\t audioAvailableChanged(true)");
+ QCOMPARE(videoAvailableSpy.count(), 1);
+ arguments = videoAvailableSpy.takeFirst();
+ QVERIFY(arguments.at(0).toBool() == false);
+ updateLog("\t videoAvailableChanged(false)");
+
+ setVideoOnlyContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ updateLog("SetMedia: videoOnlyContent");
+ WAIT_FOR_CONDITION(m_player->isVideoAvailable(), true);
+ updateLog("\t isVideoAvailable() == true");
+ QVERIFY(m_player->isAudioAvailable() == false);
+ updateLog("\t isAudioAvailable() == false");
+ QCOMPARE(audioAvailableSpy.count(), 1);
+ arguments = audioAvailableSpy.takeFirst();
+ QVERIFY(arguments.at(0).toBool() == false);
+ updateLog("\t audioAvailableChanged(false)");
+ QCOMPARE(videoAvailableSpy.count(), 1);
+ arguments = videoAvailableSpy.takeFirst();
+ QVERIFY(arguments.at(0).toBool() == true);
+ updateLog("\t videoAvailableChanged(true)");
+
+ setAudioVideoContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ updateLog("SetMedia: audioVideoContent");
+ WAIT_FOR_CONDITION(m_player->isAudioAvailable(), true);
+ updateLog("\t isAudioAvailable() == true");
+ QCOMPARE(audioAvailableSpy.count(), 1);
+ arguments = audioAvailableSpy.takeFirst();
+ QVERIFY(arguments.at(0).toBool() == true);
+ updateLog("\t audioAvailableChanged(true)");
+ QCOMPARE(videoAvailableSpy.count(), 0);
+
+ updateLog("*****testVideoAndAudioAvailability: PASSED");
+
+}
+
+void tst_QMediaPlayer_xa::testStreamInformation()
+{
+ updateLog("*****testStreamInformation");
+ resetPlayer();
+ QMediaStreamsControl* m_streamControl = (QMediaStreamsControl*)(m_player->service()->requestControl(QMediaStreamsControl_iid));
+ setVideoOnlyContent();
+
+ if(m_streamControl)
+ {
+ {
+ QSignalSpy streamInfoSpy(m_streamControl, SIGNAL(streamsChanged()));
+ setAudioOnlyContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(m_streamControl->streamCount() == 1);
+ QCOMPARE(streamInfoSpy.count(), 1);
+ }
+
+ {
+ QSignalSpy streamInfoSpy(m_streamControl, SIGNAL(streamsChanged()));
+ setAudioVideoContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(m_streamControl->streamCount() == 2);
+ QCOMPARE(streamInfoSpy.count(), 1);
+ }
+
+ {
+ QSignalSpy streamInfoSpy(m_streamControl, SIGNAL(streamsChanged()));
+ setAudioVideoContent(); //set alternate content
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(m_streamControl->streamCount() == 2);
+ QCOMPARE(streamInfoSpy.count(), 1);
+ }
+
+ {
+ QSignalSpy streamInfoSpy(m_streamControl, SIGNAL(streamsChanged()));
+ setVideoOnlyContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(m_streamControl->streamCount() == 1);
+ QCOMPARE(streamInfoSpy.count(), 1);
+ }
+
+ updateLog("*****testStreamInformation: PASSED");
+ }
+}
+
+void tst_QMediaPlayer_xa::testPlay()
+{
+ updateLog("*****testPlay");
+ resetPlayer();
+
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(m_player->media() == *mediaContent);
+ QSignalSpy spy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->play();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+
+ //Play->Play
+ {
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 0);
+ }
+
+ //Play->Pause
+ {
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->pause();
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(stateSpy.count(), 1);
+ }
+
+ //Play->Stop
+ {
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 1);
+ }
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ updateLog("*****testPlay: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testPause()
+{
+ updateLog("*****testPause");
+ resetPlayer();
+
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(m_player->media() == *mediaContent);
+ QSignalSpy spy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->pause();
+ // at present there is no support for stop->pause state transition. TODO: uncomment when support added
+ //QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ //QCOMPARE(spy.count(), 1);
+
+ //Pause->Play
+ {
+ //QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 1);
+ }
+
+ //Pause->Pause
+ {
+ m_player->pause();
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->pause();
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(stateSpy.count(), 0);
+ }
+
+ //Pause->Stop
+ {
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 1);
+ }
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ updateLog("*****testPause: PASSED");
+
+}
+
+void tst_QMediaPlayer_xa::testStop()
+{
+ updateLog("*****testStop");
+ resetPlayer();
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(m_player->media() == *mediaContent);
+
+ QSignalSpy spy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->stop();
+
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(spy.count(), 0);
+
+ //Stop->Play
+ {
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->play();
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ QCOMPARE(stateSpy.count(), 1);
+ }
+ // at present there is no support for stop->pause state transition. TODO: uncomment when support added
+ //Stop->Pause
+/* {
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->pause();
+ QCOMPARE(m_player->state(), QMediaPlayer::PausedState);
+ QCOMPARE(stateSpy.count(), 1);
+ }
+*/
+ //Stop->Stop
+ {
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QSignalSpy stateSpy(m_player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+ }
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ updateLog("*****testStop: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testMediaStatus()
+{
+ updateLog("*****testMediaStatus");
+ resetPlayer();
+
+ QSignalSpy statusSpy(m_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(statusSpy.count()>0);
+
+ {
+ QSignalSpy statusSpy(m_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QVERIFY(statusSpy.count()>0);
+ }
+
+ {
+ QSignalSpy statusSpy(m_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ m_player->setPosition(duration - 10);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ QVERIFY(statusSpy.count()>0);
+ }
+
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ updateLog("*****testMediaStatus: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testBufferStatus()
+{
+ updateLog("*****testBufferStatus");
+ resetPlayer();
+ m_player->setNotifyInterval(50); //Since default interval is 1 sec,could not receive any bufferStatusChanged SIGNAL,hence checking for 50milliseconds
+ QSignalSpy spy(m_player, SIGNAL(bufferStatusChanged(int)));
+ // setStreamingContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ WAIT_FOR_CONDITION(m_player->bufferStatus(), 100);
+ QVERIFY(spy.count()>0);
+ updateLog("*****testBufferStatus: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testPlaybackRate()
+{
+ updateLog("*****testPlaybackRate");
+
+ resetPlayer();
+
+ qreal playbackRate = 1.5;
+
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ m_player->setPlaybackRate(playbackRate);
+ QVERIFY(m_player->playbackRate() == playbackRate);
+
+ QSignalSpy spy(m_player, SIGNAL(playbackRateChanged(qreal)));
+ m_player->setPlaybackRate(playbackRate + 0.5f);
+ QCOMPARE(m_player->playbackRate(), playbackRate + 0.5f);
+ QCOMPARE(spy.count(), 1);
+
+ updateLog("*****testPlaybackRate: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testPlaybackRateWhilePlaying()
+{
+ updateLog("*****testPlaybackRateWhilePlaying");
+ resetPlayer();
+
+ qreal playbackRate = 1.5;
+
+ setAudioVideoContent();
+
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ m_player->setPlaybackRate(playbackRate);
+ QVERIFY(m_player->playbackRate() == playbackRate);
+
+ QSignalSpy spy(m_player, SIGNAL(playbackRateChanged(qreal)));
+ m_player->setPlaybackRate(playbackRate + 0.5f);
+ QCOMPARE(m_player->playbackRate(), playbackRate + 0.5f);
+ QCOMPARE(spy.count(), 1);
+
+ updateLog("*****testPlaybackRateWhilePlaying: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testSeekable()
+{
+ updateLog("*****testBufferStatus");
+ resetPlayer();
+ QSignalSpy spy(m_player, SIGNAL(seekableChanged(bool)));
+ setAudioVideoContent();
+ qint64 position = 1000;
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(m_player->isSeekable()==true);
+ m_player->setPosition(position);
+ QCOMPARE(spy.count(), 0);
+ QVERIFY(m_player->isSeekable()==true);
+
+ updateLog("*****testBufferStatus: PASSED");
+
+}
+
+void tst_QMediaPlayer_xa::testAspectRatioMode()
+{
+ updateLog("*****testBufferStatus");
+ resetPlayer();
+ setAudioVideoContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVideoWidgetControl* m_videoWidgetControl = (QVideoWidgetControl*)(m_player->service()->requestControl(QVideoWidgetControl_iid));
+
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ QCOMPARE(m_videoWidgetControl->aspectRatioMode(), Qt::KeepAspectRatio); //default
+
+ QTest::qWait(5000); //wait for 5 seconds
+
+ {
+ m_videoWidgetControl->setAspectRatioMode(Qt::IgnoreAspectRatio);
+ QCOMPARE(m_videoWidgetControl->aspectRatioMode(), Qt::IgnoreAspectRatio);
+ QTest::qWait(5000); //wait for 5 seconds
+ }
+
+ {
+ m_videoWidgetControl->setAspectRatioMode(Qt::KeepAspectRatioByExpanding);
+ QCOMPARE(m_videoWidgetControl->aspectRatioMode(), Qt::KeepAspectRatioByExpanding);
+ QTest::qWait(5000); //wait for 5 seconds
+ }
+ {
+ m_videoWidgetControl->setAspectRatioMode(Qt::KeepAspectRatio);
+ QCOMPARE(m_videoWidgetControl->aspectRatioMode(), Qt::KeepAspectRatio);
+ QTest::qWait(5000); //wait for 5 seconds
+ }
+
+ updateLog("*****testBufferStatus: PASSED");
+
+}
+
+void tst_QMediaPlayer_xa::testFullScreen()
+{
+ updateLog("*****testFullScreen");
+ resetPlayer();
+ setAudioVideoContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVideoWidgetControl* m_videoWidgetControl = (QVideoWidgetControl*)(m_player->service()->requestControl(QVideoWidgetControl_iid));
+
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ //m_widget->resize(50, 50);
+ m_widget->showNormal();
+ QTest::qWait(10000); //wait for 5 seconds
+
+
+ if(m_videoWidgetControl)
+ {
+ QSignalSpy spy(m_videoWidgetControl, SIGNAL(fullScreenChanged(bool)));
+ m_videoWidgetControl->setFullScreen(true);
+ QTest::qWait(10000); //wait for 5 seconds
+ QCOMPARE(m_videoWidgetControl->isFullScreen(), true);
+ QCOMPARE(spy.count(), 1);
+ }
+
+
+ if(m_videoWidgetControl)
+ {
+ QSignalSpy spy(m_videoWidgetControl, SIGNAL(fullScreenChanged(bool)));
+ m_videoWidgetControl->setFullScreen(false);
+ QCOMPARE(m_videoWidgetControl->isFullScreen(), false);
+ QTest::qWait(10000); //wait for 5 seconds
+ QCOMPARE(spy.count(), 1);
+ }
+
+ updateLog("*****testFullScreen: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testWindowControl_NativeSize()
+{
+ updateLog("*****testWindowControl_NativeSize");
+ resetPlayer_WindowControl();
+ setAudioVideoContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVERIFY(m_player->media() == *mediaContent);
+ m_player->play();
+ WAIT_LONG_FOR_CONDITION(m_player->state(), QMediaPlayer::PlayingState);
+ QVideoWindowControl* windowControl = (QVideoWindowControl*)(m_player->service()->requestControl(QVideoWindowControl_iid));
+ if (windowControl)
+ {
+ QSize size = windowControl->nativeSize();
+ }
+
+ WAIT_LONG_FOR_CONDITION(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ updateLog("*****testWindowControl_NativeSize: PASSED");
+}
+
+void tst_QMediaPlayer_xa::testWindowControl_AspectRatioMode()
+{
+ updateLog("*****testWindowControl_AspectRatioMode");
+ resetPlayer_WindowControl();
+ setAudioVideoContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVideoWindowControl* windowControl = (QVideoWindowControl*)(m_player->service()->requestControl(QVideoWindowControl_iid));
+
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ QCOMPARE(windowControl->aspectRatioMode(), Qt::KeepAspectRatio); //default
+
+ QTest::qWait(5000); //wait for 5 seconds
+
+ {
+ windowControl->setAspectRatioMode(Qt::IgnoreAspectRatio);
+ QCOMPARE(windowControl->aspectRatioMode(), Qt::IgnoreAspectRatio);
+ QTest::qWait(5000); //wait for 5 seconds
+ }
+
+ {
+ windowControl->setAspectRatioMode(Qt::KeepAspectRatioByExpanding);
+ QCOMPARE(windowControl->aspectRatioMode(), Qt::KeepAspectRatioByExpanding);
+ QTest::qWait(5000); //wait for 5 seconds
+ }
+ {
+ windowControl->setAspectRatioMode(Qt::KeepAspectRatio);
+ QCOMPARE(windowControl->aspectRatioMode(), Qt::KeepAspectRatio);
+ QTest::qWait(5000); //wait for 5 seconds
+ }
+
+ updateLog("*****testWindowControl_AspectRatioMode: PASSED");
+
+}
+
+void tst_QMediaPlayer_xa::testWindowControl_FullScreen()
+{
+ updateLog("*****testWindowControl_FullScreen");
+ resetPlayer_WindowControl();
+ setAudioVideoContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QVideoWindowControl* windowControl = (QVideoWindowControl*)(m_player->service()->requestControl(QVideoWindowControl_iid));
+
+ m_player->play();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+
+ //m_windowWidget->resize(250, 350);
+ m_windowWidget->showNormal();
+ QTest::qWait(10000); //wait for 5 seconds
+
+ if(windowControl)
+ {
+ QSignalSpy spy(windowControl, SIGNAL(fullScreenChanged(bool)));
+ windowControl->setFullScreen(true);
+ QTest::qWait(10000); //wait for 5 seconds
+ QCOMPARE(windowControl->isFullScreen(), true);
+ QCOMPARE(spy.count(), 1);
+ }
+
+
+ if(windowControl)
+ {
+ QSignalSpy spy(windowControl, SIGNAL(fullScreenChanged(bool)));
+ windowControl->setFullScreen(false);
+ QCOMPARE(windowControl->isFullScreen(), false);
+ QTest::qWait(10000); //wait for 5 seconds
+ QCOMPARE(spy.count(), 1);
+ }
+
+ updateLog("*****testWindowControl_FullScreen: PASSED");
+}
+
+
+//adding access-point testcase
+
+
+void tst_QMediaPlayer_xa::testSetconfigurationsAP()
+{
+ updateLog("*****testSetconfigurationsAP");
+ resetPlayer();
+
+ //Passing only valid Accesspoint in QList
+ QList<QNetworkConfiguration> configs;
+ accesspointlist = manager.allConfigurations();
+ for (int i=0; i<=accesspointlist.size()-1;i++)
+ qDebug()<<"accesspointlist"<< accesspointlist.at(i).name();
+ configs<<accesspointlist.at(8);
+ QSignalSpy spy(m_player, SIGNAL(networkConfigurationChanged(const QNetworkConfiguration&)));
+ m_player->setNetworkConfigurations(configs);
+ setStreamingContent3gp();
+ m_player->play();
+ QTest::qWait(100000);
+ WAIT_LONG_FOR_CONDITION(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE((m_player->currentNetworkConfiguration().name()), accesspointlist.at(8).name());
+ updateLog("*****testSetconfigurationsAP: PASSED");
+
+}
+
+
+void tst_QMediaPlayer_xa::testSetAccesspoint()
+{
+ updateLog("*****testSetAccesspoint");
+ resetPlayer();
+ QList<QNetworkConfiguration> configs;
+ accesspointlist = manager.allConfigurations();
+ configs<<accesspointlist.at(0);
+ configs<<accesspointlist.at(3);
+ configs<<accesspointlist.at(10);
+ configs<<accesspointlist.at(8);
+ //Passing only valid Accesspoint in QList
+ QSignalSpy spy(m_player, SIGNAL(networkConfigurationChanged(const QNetworkConfiguration&)));
+ m_player->setNetworkConfigurations(configs);
+
+ setStreamingContent3gp();
+ QTest::qWait(200000);
+ m_player->play();
+ QTest::qWait(10000);
+ WAIT_LONG_FOR_CONDITION(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE((m_player->currentNetworkConfiguration().name()), accesspointlist.at(8).name());
+
+ updateLog("*****testSetAccesspoint: PASSED");
+}
+
+
+void tst_QMediaPlayer_xa::testGetAccesspoint()
+{
+ updateLog("*****testGetAccesspoint");
+ resetPlayer();
+ //getting information about the current configured accesspoint without setting any configurations
+ QNetworkConfiguration getaccespoint;
+ getaccespoint = m_player->currentNetworkConfiguration();
+ QCOMPARE(getaccespoint.name(),QString(""));
+ updateLog("*****testGetAccesspoint: ");
+}
+
+
+void tst_QMediaPlayer_xa::testDiffmediacontentAP()
+{
+ updateLog("*****streaming Different mediacontent files via AP");
+ resetPlayer();
+ QList<QNetworkConfiguration> configs;
+ accesspointlist = manager.allConfigurations();
+ configs<<accesspointlist.at(8);
+ QSignalSpy spy(m_player, SIGNAL(networkConfigurationChanged(const QNetworkConfiguration&)));
+ m_player->setNetworkConfigurations(configs);
+ //first mediacontent file
+ setAudioStreamingContent();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ m_player->play();
+ QTest::qWait(30000);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ //second mediacontent file
+ setStreamingContent3gp();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ m_player->play();
+ QTest::qWait(20000);
+ QCOMPARE(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::EndOfMedia);
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+
+ QCOMPARE((m_player->currentNetworkConfiguration().name()), accesspointlist.at(8).name());
+ QNetworkConfiguration getaccespoint;
+ getaccespoint = m_player->currentNetworkConfiguration();
+ QCOMPARE(getaccespoint.name(), QString("MMMW"));
+
+ updateLog("*****testDiffmediacontentAP: PASSED");
+}
+
+
+void tst_QMediaPlayer_xa::testInvalidaddressAP()
+{
+ updateLog("*****testInvalidaddressAP");
+ resetPlayer();
+ //setting all invalid accesspoint
+ QList<QNetworkConfiguration> configs;
+ accesspointlist = manager.allConfigurations();
+ configs<<accesspointlist.at(0);
+ configs<<accesspointlist.at(2);
+ configs<<accesspointlist.at(3);
+ QSignalSpy spy(m_player, SIGNAL(networkConfigurationChanged(const QNetworkConfiguration&)));
+ m_player->setNetworkConfigurations(configs);
+ QNetworkConfiguration getaccespoint;
+ getaccespoint = m_player->currentNetworkConfiguration();
+ QCOMPARE(getaccespoint.name(), QString(""));
+
+ updateLog("*****testInvalidaddressAP: PASSED");
+}
+
+
+
+void tst_QMediaPlayer_xa::testMultipleAccesspoints()
+{
+ updateLog("*****testMultipleAccesspoints");
+ resetPlayer();
+ QList<QNetworkConfiguration> configs;
+ accesspointlist = manager.allConfigurations();
+ configs<<accesspointlist.at(8);
+ QSignalSpy spy(m_player, SIGNAL(networkConfigurationChanged(const QNetworkConfiguration&)));
+ m_player->setNetworkConfigurations(configs);
+ setStreamingContent3gp();
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ m_player->play();
+ WAIT_LONG_FOR_CONDITION(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QTest::qWait(20000);
+ m_player->stop();
+ QCOMPARE(m_player->state(), QMediaPlayer::StoppedState);
+ QCOMPARE((m_player->currentNetworkConfiguration().name()), accesspointlist.at(8).name());
+ //Second configuration list
+ QList<QNetworkConfiguration> secconfigs;
+ secaccesspoint = manager.allConfigurations();
+ secconfigs<<secaccesspoint.at(5);
+ QSignalSpy spy1(m_player, SIGNAL(networkConfigurationChanged(const QNetworkConfiguration&)));
+ m_player->setNetworkConfigurations(secconfigs);
+ setStreamingContent3gp();
+ // setAudioStreamingContent();
+ QTest::qWait(30000);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(m_player->mediaStatus(), QMediaPlayer::LoadedMedia);
+ m_player->play();
+ WAIT_LONG_FOR_CONDITION(m_player->state(), QMediaPlayer::PlayingState);
+ WAIT_FOR_CONDITION(m_player->mediaStatus(), QMediaPlayer::BufferedMedia);
+ QTest::qWait(10000);
+ updateLog("*****testSetAccesspoint: PASSED");
+ QCOMPARE((m_player->currentNetworkConfiguration().name()), accesspointlist.at(5).name());
+ QNetworkConfiguration getaccespoint;
+ getaccespoint = m_player->currentNetworkConfiguration();
+ QCOMPARE(getaccespoint.name(), QString("Mobile Office"));
+
+ updateLo