Merge lp:~phablet-team/qtubuntu-media/fix-1449790 into lp:qtubuntu-media

Proposed by Jim Hodapp
Status: Merged
Approved by: Alfonso Sanchez-Beato
Approved revision: 106
Merged at revision: 101
Proposed branch: lp:~phablet-team/qtubuntu-media/fix-1449790
Merge into: lp:qtubuntu-media
Diff against target: 2525 lines (+1300/-1040)
14 files modified
README (+7/-0)
src/aal/aalmediaplayerservice.cpp (+10/-2)
src/aal/aalmediaplaylistprovider.cpp (+24/-9)
tests/integration/integration.pro (+6/-23)
tests/integration/playlists/playlists.pro (+25/-0)
tests/integration/playlists/tst_mediaplaylist.cpp (+896/-0)
tests/integration/playlists/tst_mediaplaylist.h (+110/-0)
tests/integration/tst_mediaplaylist.cpp (+0/-896)
tests/integration/tst_mediaplaylist.h (+0/-110)
tests/integration/uris/generate_test_files.sh (+25/-0)
tests/integration/uris/remove_test_files.sh (+7/-0)
tests/integration/uris/tst_mediauris.cpp (+116/-0)
tests/integration/uris/tst_mediauris.h (+51/-0)
tests/integration/uris/uris.pro (+23/-0)
To merge this branch: bzr merge lp:~phablet-team/qtubuntu-media/fix-1449790
Reviewer Review Type Date Requested Status
Alfonso Sanchez-Beato Approve
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+285814@code.launchpad.net

Commit message

URI encode the URI that we call setMedia() on or add to the playlist

Description of the change

URI encode the URI that we call setMedia() on or add to the playlist

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
104. By Jim Hodapp

Make sure to URI encode the track paths that get added via playlists

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

My main concern with this change is whether we handle properly UTF-8 or not. The toLocal8Bit() suggests we might be breaking support for non-ascii file names (although I am not sure if we supported that before).

I think it is a good opportunity to add tests for UTF-8 (this MP adds infrastructure for that, like generate_test_files.sh, which is great) and make sure those files get played as expected.

Finally, I have an inline comment.

review: Needs Fixing
105. By Jim Hodapp

Simply pass the URL string through to media-hub, no longer need to do any special handling since media-hub takes care of it all

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Looks good, but you have forgotten to remove encode_uri() (it is not used anymore).

review: Needs Fixing
106. By Jim Hodapp

Added another integration test that checks special character handling for setMedia()

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

LGTM

review: Approve
107. By Jim Hodapp

Added README note for how to manually run the integrations tests

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'README'
--- README 2015-09-09 15:13:10 +0000
+++ README 2016-02-22 16:57:32 +0000
@@ -1,3 +1,10 @@
1Integrations Tests:
2-------------------
3* Currently, the integration tests are disabled by default. To utilize them, you first need to
4 uncomment the last line in tests/tests.pro (starts with "system"). Then from the build/ dir,
5 run qmake -r .. followed by make. After it's done building, cd to each integration test's dir
6 within build/ and manually run each test's binary.
7
1Coding Convention:8Coding Convention:
2------------------9------------------
310
411
=== modified file 'src/aal/aalmediaplayerservice.cpp'
--- src/aal/aalmediaplayerservice.cpp 2016-01-14 19:56:59 +0000
+++ src/aal/aalmediaplayerservice.cpp 2016-02-22 16:57:32 +0000
@@ -312,14 +312,19 @@
312 if (m_mediaPlaylistProvider && url.isEmpty())312 if (m_mediaPlaylistProvider && url.isEmpty())
313 m_mediaPlaylistProvider->clear();313 m_mediaPlaylistProvider->clear();
314314
315 const media::Track::UriType uri(url.url().toStdString());
316 if (m_mediaPlaylistProvider == nullptr || m_mediaPlaylistProvider->mediaCount() == 0)315 if (m_mediaPlaylistProvider == nullptr || m_mediaPlaylistProvider->mediaCount() == 0)
317 {316 {
318 try {317 try {
319 m_hubPlayerSession->open_uri(uri);318 m_hubPlayerSession->open_uri(url.toString().toStdString());
320 }319 }
321 catch (const media::Player::Errors::InsufficientAppArmorPermissions &e) {320 catch (const media::Player::Errors::InsufficientAppArmorPermissions &e) {
322 qWarning() << e.what();321 qWarning() << e.what();
322 signalQMediaPlayerError(media::Player::Error::resource_error);
323 return;
324 }
325 catch (const media::Player::Errors::UriNotFound &e) {
326 qWarning() << e.what();
327 signalQMediaPlayerError(media::Player::Error::resource_error);
323 return;328 return;
324 }329 }
325 catch (const std::runtime_error &e) {330 catch (const std::runtime_error &e) {
@@ -631,10 +636,12 @@
631 case media::Player::Error::resource_error:636 case media::Player::Error::resource_error:
632 outError = QMediaPlayer::ResourceError;637 outError = QMediaPlayer::ResourceError;
633 outErrorStr = "A media resource couldn't be resolved.";638 outErrorStr = "A media resource couldn't be resolved.";
639 m_mediaPlayerControl->setMediaStatus(QMediaPlayer::InvalidMedia);
634 break;640 break;
635 case media::Player::Error::format_error:641 case media::Player::Error::format_error:
636 outError = QMediaPlayer::FormatError;642 outError = QMediaPlayer::FormatError;
637 outErrorStr = "The media format type is not playable due to a missing codec.";643 outErrorStr = "The media format type is not playable due to a missing codec.";
644 m_mediaPlayerControl->setMediaStatus(QMediaPlayer::InvalidMedia);
638 break;645 break;
639 case media::Player::Error::network_error:646 case media::Player::Error::network_error:
640 outError = QMediaPlayer::NetworkError;647 outError = QMediaPlayer::NetworkError;
@@ -643,6 +650,7 @@
643 case media::Player::Error::access_denied_error:650 case media::Player::Error::access_denied_error:
644 outError = QMediaPlayer::AccessDeniedError;651 outError = QMediaPlayer::AccessDeniedError;
645 outErrorStr = "Insufficient privileges to play that media.";652 outErrorStr = "Insufficient privileges to play that media.";
653 m_mediaPlayerControl->setMediaStatus(QMediaPlayer::InvalidMedia);
646 break;654 break;
647 case media::Player::Error::service_missing_error:655 case media::Player::Error::service_missing_error:
648 outError = QMediaPlayer::ServiceMissingError;656 outError = QMediaPlayer::ServiceMissingError;
649657
=== modified file 'src/aal/aalmediaplaylistprovider.cpp'
--- src/aal/aalmediaplaylistprovider.cpp 2016-01-05 16:58:37 +0000
+++ src/aal/aalmediaplaylistprovider.cpp 2016-02-22 16:57:32 +0000
@@ -108,8 +108,8 @@
108 }108 }
109109
110 const QUrl url = content.canonicalUrl();110 const QUrl url = content.canonicalUrl();
111 std::string urlStr = AalUtility::unescape_str(content);111 std::string urlStr = url.toString().toStdString();
112 if (url.scheme().isEmpty() and url.scheme() != "file")112 if (url.scheme().isEmpty())
113 urlStr = "file://" + urlStr;113 urlStr = "file://" + urlStr;
114114
115 static const bool make_current = false;115 static const bool make_current = false;
@@ -123,11 +123,19 @@
123 }123 }
124 catch (const media::TrackList::Errors::InsufficientPermissionsToAddTrack &e)124 catch (const media::TrackList::Errors::InsufficientPermissionsToAddTrack &e)
125 {125 {
126 qWarning() << "Failed to add track '" << content.canonicalUrl().toString() << "' to playlist: " << e.what();126 qWarning() << "Failed to add track '" << content.canonicalUrl().toString()
127 << "' to playlist:" << e.what();
128 return false;
129 }
130 catch (const media::Player::Errors::UriNotFound &e)
131 {
132 qWarning() << "Failed to add track '" << content.canonicalUrl().toString()
133 << "' to playlist:" << e.what();
127 return false;134 return false;
128 }135 }
129 catch (const std::runtime_error &e) {136 catch (const std::runtime_error &e) {
130 qWarning() << "Failed to add track '" << content.canonicalUrl().toString() << "' to playlist: " << e.what();137 qWarning() << "Failed to add track '" << content.canonicalUrl().toString()
138 << "' to playlist: " << e.what();
131 return false;139 return false;
132 }140 }
133141
@@ -149,9 +157,9 @@
149 media::TrackList::ContainerURI uris;157 media::TrackList::ContainerURI uris;
150 for (const auto mediaContent : contentList) {158 for (const auto mediaContent : contentList) {
151#ifdef VERBOSE_DEBUG159#ifdef VERBOSE_DEBUG
152 qDebug() << "Adding track " << AalUtility::unescape(mediaContent).toString();160 qDebug() << "Adding track " << mediaContent.canonicalUrl().toString().toStdString();
153#endif161#endif
154 uris.push_back(AalUtility::unescape_str(mediaContent));162 uris.push_back(mediaContent.canonicalUrl().toString().toStdString());
155 }163 }
156164
157 const media::Track::Id after_empty_track = media::TrackList::after_empty_track();165 const media::Track::Id after_empty_track = media::TrackList::after_empty_track();
@@ -165,6 +173,11 @@
165 qWarning() << "Failed to add" << contentList.size() << "tracks to playlist: " << e.what();173 qWarning() << "Failed to add" << contentList.size() << "tracks to playlist: " << e.what();
166 return false;174 return false;
167 }175 }
176 catch (const media::Player::Errors::UriNotFound &e)
177 {
178 qWarning() << "Failed to add certain tracks to playlist: " << e.what();
179 return false;
180 }
168 catch (const std::runtime_error &e) {181 catch (const std::runtime_error &e) {
169 qWarning() << "Failed to add" << contentList.size() << "tracks to playlist: " << e.what();182 qWarning() << "Failed to add" << contentList.size() << "tracks to playlist: " << e.what();
170 return false;183 return false;
@@ -186,7 +199,7 @@
186 }199 }
187200
188 const QUrl url = content.canonicalUrl();201 const QUrl url = content.canonicalUrl();
189 std::string urlStr = AalUtility::unescape_str(content);202 std::string urlStr = url.toString().toStdString();
190 if (url.scheme().isEmpty() and url.scheme() != "file")203 if (url.scheme().isEmpty() and url.scheme() != "file")
191 urlStr = "file://" + urlStr;204 urlStr = "file://" + urlStr;
192205
@@ -212,11 +225,13 @@
212 }225 }
213 catch (const media::TrackList::Errors::InsufficientPermissionsToAddTrack &e)226 catch (const media::TrackList::Errors::InsufficientPermissionsToAddTrack &e)
214 {227 {
215 qWarning() << "Failed to add track '" << content.canonicalUrl().toString() << "' to playlist: " << e.what();228 qWarning() << "Failed to add track '" << content.canonicalUrl().toString()
229 << "' to playlist: " << e.what();
216 return false;230 return false;
217 }231 }
218 catch (const std::runtime_error &e) {232 catch (const std::runtime_error &e) {
219 qWarning() << "Failed to add track '" << content.canonicalUrl().toString() << "' to playlist: " << e.what();233 qWarning() << "Failed to add track '" << content.canonicalUrl().toString()
234 << "' to playlist: " << e.what();
220 return false;235 return false;
221 }236 }
222237
223238
=== modified file 'tests/integration/integration.pro'
--- tests/integration/integration.pro 2015-11-03 15:58:40 +0000
+++ tests/integration/integration.pro 2016-02-22 16:57:32 +0000
@@ -1,23 +1,6 @@
1include(../../coverage.pri)1include(coverage.pri)
22
3CONFIG += testcase3TEMPLATE = subdirs
4QMAKE_CXXFLAGS += -std=c++114
5DEFINES += QT_NO_KEYWORDS5SUBDIRS += uris
6TARGET = tst_integration6SUBDIRS += playlists
7
8QT += core multimedia testlib
9
10QT_TESTCASE_BUILDDIR = .
11
12INCLUDEPATH += ../../src/aal \
13 /usr/include/qt5/QtMultimedia \
14
15HEADERS += \
16 tst_mediaplaylist.h
17
18SOURCES += \
19 tst_mediaplaylist.cpp \
20 ../../src/aal/aalutility.cpp
21
22# media-hub is required to be running for these tests
23#system(/sbin/stop media-hub; /sbin/start media-hub)
247
=== added directory 'tests/integration/playlists'
=== added file 'tests/integration/playlists/playlists.pro'
--- tests/integration/playlists/playlists.pro 1970-01-01 00:00:00 +0000
+++ tests/integration/playlists/playlists.pro 2016-02-22 16:57:32 +0000
@@ -0,0 +1,25 @@
1include(../../coverage.pri)
2
3CONFIG += testcase
4QMAKE_CXXFLAGS += -std=c++11
5DEFINES += QT_NO_KEYWORDS
6TARGET = tst_playlists
7
8QT += core multimedia testlib
9
10QT_TESTCASE_BUILDDIR = .
11
12INCLUDEPATH += ../../src/aal \
13 /usr/include/qt5/QtMultimedia \
14
15HEADERS += \
16 tst_mediaplaylist.h
17
18SOURCES += \
19 tst_mediaplaylist.cpp \
20 ../../../src/aal/aalutility.cpp
21
22SUBDIRS += uris
23
24# media-hub is required to be running for these tests
25#system(/sbin/stop media-hub; /sbin/start media-hub)
026
=== added directory 'tests/integration/playlists/testdata'
=== added file 'tests/integration/playlists/testdata/Ubuntu.ogg'
1Binary files tests/integration/playlists/testdata/Ubuntu.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/Ubuntu.ogg 2016-02-22 16:57:32 +0000 differ27Binary files tests/integration/playlists/testdata/Ubuntu.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/Ubuntu.ogg 2016-02-22 16:57:32 +0000 differ
=== added file 'tests/integration/playlists/testdata/testfile.mp4'
2Binary files tests/integration/playlists/testdata/testfile.mp4 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile.mp4 2016-02-22 16:57:32 +0000 differ28Binary files tests/integration/playlists/testdata/testfile.mp4 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile.mp4 2016-02-22 16:57:32 +0000 differ
=== added file 'tests/integration/playlists/testdata/testfile.ogg'
3Binary files tests/integration/playlists/testdata/testfile.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile.ogg 2016-02-22 16:57:32 +0000 differ29Binary files tests/integration/playlists/testdata/testfile.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile.ogg 2016-02-22 16:57:32 +0000 differ
=== added file 'tests/integration/playlists/testdata/testfile1.ogg'
4Binary files tests/integration/playlists/testdata/testfile1.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile1.ogg 2016-02-22 16:57:32 +0000 differ30Binary files tests/integration/playlists/testdata/testfile1.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile1.ogg 2016-02-22 16:57:32 +0000 differ
=== added file 'tests/integration/playlists/testdata/testfile2.ogg'
5Binary files tests/integration/playlists/testdata/testfile2.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile2.ogg 2016-02-22 16:57:32 +0000 differ31Binary files tests/integration/playlists/testdata/testfile2.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile2.ogg 2016-02-22 16:57:32 +0000 differ
=== added file 'tests/integration/playlists/testdata/testfile3.ogg'
6Binary files tests/integration/playlists/testdata/testfile3.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile3.ogg 2016-02-22 16:57:32 +0000 differ32Binary files tests/integration/playlists/testdata/testfile3.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile3.ogg 2016-02-22 16:57:32 +0000 differ
=== added file 'tests/integration/playlists/testdata/testfile4.ogg'
7Binary files tests/integration/playlists/testdata/testfile4.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile4.ogg 2016-02-22 16:57:32 +0000 differ33Binary files tests/integration/playlists/testdata/testfile4.ogg 1970-01-01 00:00:00 +0000 and tests/integration/playlists/testdata/testfile4.ogg 2016-02-22 16:57:32 +0000 differ
=== added file 'tests/integration/playlists/tst_mediaplaylist.cpp'
--- tests/integration/playlists/tst_mediaplaylist.cpp 1970-01-01 00:00:00 +0000
+++ tests/integration/playlists/tst_mediaplaylist.cpp 2016-02-22 16:57:32 +0000
@@ -0,0 +1,896 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "tst_mediaplaylist.h"
18#include "../../../src/aal/aalutility.h"
19
20#include <thread>
21#include <unistd.h>
22
23#include <QMediaPlayer>
24#include <QMediaPlaylist>
25
26#include <QtTest/QtTest>
27
28void tst_MediaPlaylist::initTestCase()
29{
30}
31
32void tst_MediaPlaylist::cleanupTestCase()
33{
34}
35
36void tst_MediaPlaylist::init()
37{
38 // NOTE: This sleep is currently needed in order to give media-hub a bit of time
39 // between our different tests to cleanup and come back in a state where it can
40 // respond to our requests.
41 sleep(1);
42}
43
44void tst_MediaPlaylist::constructDestroyRepeat()
45{
46 for (int i=0; i<25; i++)
47 {
48 QMediaPlayer *player = new QMediaPlayer;
49 QMediaPlaylist *playlist = new QMediaPlaylist;
50 player->setPlaylist(playlist);
51
52 delete playlist;
53 delete player;
54 }
55}
56
57void tst_MediaPlaylist::addTwoTracksAndVerify()
58{
59 QMediaPlayer *player = new QMediaPlayer;
60 QMediaPlaylist *playlist = new QMediaPlaylist;
61 player->setPlaylist(playlist);
62
63 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
64 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
65
66 QCOMPARE(playlist->mediaCount(), 2);
67
68 delete playlist;
69 delete player;
70}
71
72void tst_MediaPlaylist::insertTracksAtPositionAndVerify()
73{
74 QMediaPlayer *player = new QMediaPlayer;
75 QMediaPlaylist *playlist = new QMediaPlaylist;
76 player->setPlaylist(playlist);
77
78 QElapsedTimer timer;
79 timer.start();
80 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
81 waitTrackInserted(playlist);
82 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
83 waitTrackInserted(playlist);
84 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
85 waitTrackInserted(playlist);
86 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
87 waitTrackInserted(playlist);
88 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
89 waitTrackInserted(playlist);
90 qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
91
92 QCOMPARE(playlist->mediaCount(), 5);
93
94 const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
95 playlist->insertMedia(2, insertedTrack);
96 waitTrackInserted(playlist);
97
98 qDebug() << "playlist->media(2):" << playlist->media(2).canonicalUrl();
99 qDebug() << "insertedTrack:" << insertedTrack.canonicalUrl();
100 QCOMPARE(playlist->media(2), insertedTrack);
101
102 delete playlist;
103 delete player;
104}
105
106void tst_MediaPlaylist::moveTrackAndVerify()
107{
108 QMediaPlayer *player = new QMediaPlayer;
109 QMediaPlaylist *playlist = new QMediaPlaylist;
110 player->setPlaylist(playlist);
111
112 QElapsedTimer timer;
113 timer.start();
114 QList<QMediaContent> content;
115 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
116 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
117 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
118 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
119 const QMediaContent newLastTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
120 content.push_back(newLastTrack);
121 const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
122 content.push_back(insertedTrack);
123 playlist->addMedia(content);
124 waitTrackInserted(playlist);
125 qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
126
127 QCOMPARE(playlist->mediaCount(), 6);
128
129 connectSignal(playlist, Signals::MediaRemoved);
130 connectSignal(playlist, Signals::MediaInserted);
131 playlist->moveMedia(5, 2);
132
133 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
134 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
135 QCOMPARE(playlist->mediaCount(), 6);
136
137 delete playlist;
138 delete player;
139}
140
141void tst_MediaPlaylist::movePlayingTrackAndVerify()
142{
143 QMediaPlayer *player = new QMediaPlayer;
144 QMediaPlaylist *playlist = new QMediaPlaylist;
145 player->setPlaylist(playlist);
146
147 QElapsedTimer timer;
148 timer.start();
149 QList<QMediaContent> content;
150 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
151 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
152 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
153 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
154 const QMediaContent newLastTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
155 content.push_back(newLastTrack);
156 const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/Ubuntu.ogg")));
157 content.push_back(insertedTrack);
158 playlist->addMedia(content);
159 waitTrackInserted(playlist);
160 qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
161
162 playlist->setCurrentIndex(5);
163 waitCurrentIndexChange(playlist);
164 QCOMPARE(playlist->currentIndex(), 5);
165
166 player->play();
167
168 QCOMPARE(playlist->mediaCount(), 6);
169
170 sleep(2);
171
172 connectSignal(playlist, Signals::MediaRemoved);
173 connectSignal(playlist, Signals::MediaInserted);
174 playlist->moveMedia(5, 2);
175
176 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
177 qDebug() << "Verifying the presence of MediaInserted signal in deque";
178 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
179 QCOMPARE(playlist->mediaCount(), 6);
180
181 waitCurrentIndexChange(playlist);
182
183 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
184 QCOMPARE(playlist->currentIndex(), 2);
185
186 delete playlist;
187 delete player;
188}
189
190void tst_MediaPlaylist::addListOfTracksAndVerify()
191{
192 QMediaPlayer *player = new QMediaPlayer;
193 QMediaPlaylist *playlist = new QMediaPlaylist;
194 player->setPlaylist(playlist);
195
196 QList<QMediaContent> content;
197 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
198 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
199
200 playlist->addMedia(content);
201
202 QCOMPARE(playlist->mediaCount(), 2);
203
204 delete playlist;
205 delete player;
206}
207
208void tst_MediaPlaylist::addLargeListOfTracksAndVerify()
209{
210 QMediaPlayer *player = new QMediaPlayer;
211 QMediaPlaylist *playlist = new QMediaPlaylist;
212 player->setPlaylist(playlist);
213
214 // Total number of tracks added will be iterations * 5
215 const uint16_t iterations = 20;
216 QElapsedTimer timer;
217 timer.start();
218 for (uint16_t i=0; i<iterations; i++)
219 {
220 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
221 waitTrackInserted(playlist);
222 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
223 waitTrackInserted(playlist);
224 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
225 waitTrackInserted(playlist);
226 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
227 waitTrackInserted(playlist);
228 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
229 waitTrackInserted(playlist);
230 }
231 qDebug() << "** addMedia loop took" << timer.elapsed() << "milliseconds";
232
233 QCOMPARE(playlist->mediaCount(), iterations * 5);
234
235 delete playlist;
236 delete player;
237}
238
239void tst_MediaPlaylist::addLargeListOfTracksAtOnceAndVerify()
240{
241 QMediaPlayer *player = new QMediaPlayer;
242 QMediaPlaylist *playlist = new QMediaPlaylist;
243 player->setPlaylist(playlist);
244
245 QList<QMediaContent> content;
246 int i;
247 for (i=0; i<20; i++)
248 {
249 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
250 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
251 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
252 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
253 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
254 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
255 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
256 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
257 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
258 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
259 }
260
261 QElapsedTimer timer;
262 timer.start();
263 playlist->addMedia(content);
264 qDebug() << "** addMedia(QList) took" << timer.elapsed() << "milliseconds";
265
266 waitTrackInserted(playlist);
267 QCOMPARE(playlist->mediaCount(), i * 10);
268
269 delete playlist;
270 delete player;
271}
272
273void tst_MediaPlaylist::addTwoListsOfTracksAtOnceAndVerify()
274{
275 QMediaPlayer *player = new QMediaPlayer;
276 QMediaPlaylist *playlist = new QMediaPlaylist;
277 player->setPlaylist(playlist);
278
279 QList<QMediaContent> content1;
280 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
281 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
282 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
283 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
284 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
285 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
286 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
287 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
288 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
289 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
290
291 QList<QMediaContent> content2;
292 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
293 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
294 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
295 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
296 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
297 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
298 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
299 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
300 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
301 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
302
303 QElapsedTimer timer;
304 timer.start();
305 playlist->addMedia(content1);
306 qDebug() << "** First list addMedia(QList) took" << timer.elapsed() << "milliseconds";
307
308 waitTrackInserted(playlist);
309 QCOMPARE(playlist->mediaCount(), 10);
310
311 timer.invalidate();
312 timer.start();
313 playlist->addMedia(content2);
314 qDebug() << "** Second list addMedia(QList) took" << timer.elapsed() << "milliseconds";
315
316 waitTrackInserted(playlist);
317 QCOMPARE(playlist->mediaCount(), 20);
318
319 delete playlist;
320 delete player;
321}
322
323void tst_MediaPlaylist::goToNextTrack()
324{
325 QMediaPlayer *player = new QMediaPlayer;
326 QMediaPlaylist *playlist = new QMediaPlaylist;
327 player->setPlaylist(playlist);
328
329 const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
330 const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
331 qDebug() << "audio URL: " << audio.toString();
332 qDebug() << "video URL: " << video.toString();
333 playlist->addMedia(audio);
334 playlist->addMedia(video);
335
336 QCOMPARE(playlist->mediaCount(), 2);
337
338 player->play();
339
340 QCoreApplication::processEvents();
341
342 const QUrl audioToVerify(playlist->currentMedia().canonicalUrl());
343 QCOMPARE(audioToVerify, audio);
344
345 playlist->next();
346
347 QCoreApplication::processEvents();
348
349 const QUrl videoToVerify(playlist->currentMedia().canonicalUrl());
350 QCOMPARE(videoToVerify, video);
351
352 delete playlist;
353 delete player;
354}
355
356void tst_MediaPlaylist::goToPreviousTrack()
357{
358 QMediaPlayer *player = new QMediaPlayer;
359 QMediaPlaylist *playlist = new QMediaPlaylist;
360 player->setPlaylist(playlist);
361
362 const QUrl audio1(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
363 const QUrl audio2(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
364 playlist->addMedia(audio1);
365 playlist->addMedia(audio2);
366
367 QCOMPARE(playlist->mediaCount(), 2);
368 playlist->setCurrentIndex(1);
369
370 player->play();
371
372 QCoreApplication::processEvents();
373
374 const QUrl audio2ToVerify(playlist->currentMedia().canonicalUrl());
375 QCOMPARE(audio2ToVerify, audio2);
376
377 playlist->previous();
378
379 QCoreApplication::processEvents();
380
381 const QUrl audio1ToVerify(playlist->currentMedia().canonicalUrl());
382 QCOMPARE(audio2ToVerify, audio1);
383 QCOMPARE(playlist->currentIndex(), 0);
384
385 delete playlist;
386 delete player;
387}
388
389void tst_MediaPlaylist::verifyMedia()
390{
391 QMediaPlayer *player = new QMediaPlayer;
392 QMediaPlaylist *playlist = new QMediaPlaylist;
393 player->setPlaylist(playlist);
394
395 const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
396 const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
397 qDebug() << "audio URL: " << audio.toString();
398 qDebug() << "video URL: " << video.toString();
399 playlist->addMedia(audio);
400 playlist->addMedia(video);
401
402 QCOMPARE(playlist->mediaCount(), 2);
403
404 const QUrl audioToVerify(playlist->media(0).canonicalUrl());
405 QCOMPARE(audioToVerify, audio);
406
407 const QUrl videoToVerify(playlist->media(1).canonicalUrl());
408 QCOMPARE(videoToVerify, video);
409
410 delete playlist;
411 delete player;
412}
413
414void tst_MediaPlaylist::removeTrackAndVerify()
415{
416 QMediaPlayer *player = new QMediaPlayer;
417 QMediaPlaylist *playlist = new QMediaPlaylist;
418 player->setPlaylist(playlist);
419
420 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
421 const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
422 playlist->addMedia(video);
423
424 waitTrackInserted(playlist);
425 QCOMPARE(playlist->mediaCount(), 2);
426
427 playlist->removeMedia(0);
428
429 QCOMPARE(playlist->mediaCount(), 1);
430
431 const QUrl videoToVerify(playlist->media(0).canonicalUrl());
432 QCOMPARE(videoToVerify, video);
433
434 delete playlist;
435 delete player;
436}
437
438void tst_MediaPlaylist::removeCurrentNonPlayingTrackAndVerify()
439{
440 QMediaPlayer *player = new QMediaPlayer;
441 QMediaPlaylist *playlist = new QMediaPlaylist;
442 player->setPlaylist(playlist);
443
444 QList<QMediaContent> content1;
445 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
446 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
447 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
448 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
449 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
450 playlist->addMedia(content1);
451 const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
452 playlist->addMedia(track);
453
454 waitTrackInserted(playlist);
455 QCOMPARE(playlist->mediaCount(), 6);
456
457 playlist->setCurrentIndex(2);
458 // Wait for the currentMediaChanged signal to be emited
459 waitTrackChange(playlist);
460 // We should not be automatically playing
461 QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
462 QCOMPARE(playlist->currentIndex(), 2);
463
464 playlist->removeMedia(2);
465
466 // We should still not be playing
467 QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
468
469 QCOMPARE(playlist->mediaCount(), 5);
470
471 const QUrl trackToVerify(playlist->media(4).canonicalUrl());
472 QCOMPARE(trackToVerify, track);
473
474 delete playlist;
475 delete player;
476}
477
478void tst_MediaPlaylist::removeCurrentPlayingTrackAndVerify()
479{
480 QMediaPlayer *player = new QMediaPlayer;
481 QMediaPlaylist *playlist = new QMediaPlaylist;
482 player->setPlaylist(playlist);
483
484 QList<QMediaContent> content1;
485 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
486 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
487 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
488 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
489 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
490 playlist->addMedia(content1);
491 const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
492 playlist->addMedia(track);
493
494 waitTrackInserted(playlist);
495 QCOMPARE(playlist->mediaCount(), 6);
496
497 player->play();
498
499 playlist->setCurrentIndex(2);
500 // Wait for the currentMediaChanged signal to be emited
501 waitTrackChange(playlist);
502 // We be playing
503 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
504 QCOMPARE(playlist->currentIndex(), 2);
505
506 playlist->removeMedia(2);
507
508 // We should still be playing
509 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
510
511 QCOMPARE(playlist->mediaCount(), 5);
512
513 const QUrl trackToVerify(playlist->media(4).canonicalUrl());
514 QCOMPARE(trackToVerify, track);
515
516 delete playlist;
517 delete player;
518}
519
520void tst_MediaPlaylist::removeLastCurrentPlayingTrackAndVerify()
521{
522 QMediaPlayer *player = new QMediaPlayer;
523 QMediaPlaylist *playlist = new QMediaPlaylist;
524 player->setPlaylist(playlist);
525
526 const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
527 playlist->addMedia(track);
528
529 waitTrackInserted(playlist);
530 QCOMPARE(playlist->mediaCount(), 1);
531
532 player->play();
533
534 playlist->setCurrentIndex(0);
535 qDebug() << "Waiting for playback status to change to playing";
536 // Wait for the currentMediaChanged signal to be emited
537 waitTrackChange(playlist);
538 // We be playing
539 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
540
541 qDebug() << "Removing track index 0";
542 playlist->removeMedia(0);
543
544 waitTrackRemoved(playlist);
545 // We should no longer be playing
546 QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
547
548 QCOMPARE(playlist->mediaCount(), 0);
549
550 delete playlist;
551 delete player;
552}
553
554void tst_MediaPlaylist::verifyCurrentIndex()
555{
556 QMediaPlayer *player = new QMediaPlayer;
557 QMediaPlaylist *playlist = new QMediaPlaylist;
558 player->setPlaylist(playlist);
559
560 QList<QMediaContent> content;
561 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
562 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
563 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
564 playlist->addMedia(content);
565
566 waitTrackInserted(playlist);
567 QCOMPARE(playlist->mediaCount(), 3);
568
569 qDebug() << "Setting current index to be 1";
570 playlist->setCurrentIndex(1);
571
572 // Wait for the currentMediaChanged signal to be emited
573 waitTrackChange(playlist);
574
575 qDebug() << "Checking if current index is 1";
576 QCOMPARE(playlist->currentIndex(), 1);
577
578 delete playlist;
579 delete player;
580}
581
582void tst_MediaPlaylist::verifyNextIndex()
583{
584 QMediaPlayer *player = new QMediaPlayer;
585 QMediaPlaylist *playlist = new QMediaPlaylist;
586 player->setPlaylist(playlist);
587
588 QList<QMediaContent> content;
589 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
590 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
591 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
592 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
593 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
594 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
595 playlist->addMedia(content);
596
597 waitTrackInserted(playlist);
598 QCOMPARE(playlist->mediaCount(), 6);
599
600 QCOMPARE(playlist->nextIndex(1), 1);
601 QCOMPARE(playlist->nextIndex(4), 4);
602 QCOMPARE(playlist->nextIndex(6), 0);
603 QCOMPARE(playlist->nextIndex(7), 1);
604 QCOMPARE(playlist->nextIndex(11), 5);
605
606 delete playlist;
607 delete player;
608}
609
610void tst_MediaPlaylist::verifyPreviousIndex()
611{
612 QMediaPlayer *player = new QMediaPlayer;
613 QMediaPlaylist *playlist = new QMediaPlaylist;
614 player->setPlaylist(playlist);
615
616 QList<QMediaContent> content;
617 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
618 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
619 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
620 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
621 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
622 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
623 playlist->addMedia(content);
624
625 waitTrackInserted(playlist);
626 QCOMPARE(playlist->mediaCount(), 6);
627
628 QCOMPARE(playlist->previousIndex(1), 5);
629 QCOMPARE(playlist->previousIndex(4), 2);
630 QCOMPARE(playlist->previousIndex(6), 0);
631 QCOMPARE(playlist->previousIndex(11), 1);
632 QCOMPARE(playlist->previousIndex(21), 3);
633 QCOMPARE(playlist->previousIndex(19), 5);
634
635 delete playlist;
636 delete player;
637}
638
639void tst_MediaPlaylist::verifyPlaybackModeCurrentItemInLoop()
640{
641 QMediaPlayer *player = new QMediaPlayer;
642 QMediaPlaylist *playlist = new QMediaPlaylist;
643 player->setPlaylist(playlist);
644
645 connectSignal(playlist, Signals::MediaInserted);
646
647 QList<QMediaContent> content;
648 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
649 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
650 playlist->addMedia(content);
651
652 // Wait until the first track is set as the current one
653 waitTrackChange(playlist);
654 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
655 QCOMPARE(playlist->mediaCount(), 2);
656
657 waitPlaybackModeChange(playlist, [playlist]()
658 {
659 playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
660 });
661
662 player->play();
663
664 // Wait for the currentMediaChanged signal to be emited
665 waitTrackChange(playlist);
666
667 QCOMPARE(playlist->currentIndex(), 0);
668
669 delete playlist;
670 delete player;
671}
672
673void tst_MediaPlaylist::verifyPlaybackModeSequential()
674{
675 QMediaPlayer *player = new QMediaPlayer;
676 QMediaPlaylist *playlist = new QMediaPlaylist;
677 player->setPlaylist(playlist);
678
679 connectSignal(playlist, Signals::MediaInserted);
680
681 QList<QMediaContent> content;
682 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
683 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
684 playlist->addMedia(content);
685
686 // Wait until the first track is set as the current one
687 waitTrackChange(playlist);
688 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
689 QCOMPARE(playlist->mediaCount(), 2);
690
691 waitPlaybackModeChange(playlist, [playlist]()
692 {
693 playlist->setPlaybackMode(QMediaPlaylist::Sequential);
694 });
695
696 player->play();
697
698 // Wait until the second track is selected
699 waitTrackChange(playlist);
700
701 QCOMPARE(playlist->currentIndex(), 1);
702
703 delete playlist;
704 delete player;
705}
706
707void tst_MediaPlaylist::playReusePlayTrackList()
708{
709 QMediaPlayer *player = new QMediaPlayer;
710 QMediaPlaylist *playlist = new QMediaPlaylist;
711 player->setPlaylist(playlist);
712
713 const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
714 const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
715
716 for (int i = 0; i < 5; ++i) {
717 playlist->addMedia(audio);
718 waitTrackInserted(playlist);
719 playlist->addMedia(video);
720 waitTrackInserted(playlist);
721 playlist->addMedia(audio);
722 waitTrackInserted(playlist);
723 QCOMPARE(playlist->mediaCount(), 3);
724
725 player->play();
726
727 const QUrl audioToVerify(playlist->currentMedia().canonicalUrl());
728 QCOMPARE(audioToVerify, audio);
729
730 player->stop();
731
732 connectSignal(playlist, Signals::MediaRemoved);
733 playlist->clear();
734
735 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
736
737 QCOMPARE(playlist->mediaCount(), 0);
738 }
739
740 delete playlist;
741 delete player;
742}
743
744template<typename R>
745void tst_MediaPlaylist::wait_for_signal(std::future<R> const& f)
746{
747 while (!is_ready<R>(f))
748 {
749 // Make sure we don't block the main QEventLoop, which
750 // would hinder receiving the currentMediaChanged event above
751 QCoreApplication::processEvents();
752 std::this_thread::yield();
753 }
754}
755
756void tst_MediaPlaylist::waitTrackChange(QMediaPlaylist *playlist)
757{
758 QMediaContent current_media;
759 std::promise<QMediaContent> promise;
760 std::future<QMediaContent> future{promise.get_future()};
761
762 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::currentMediaChanged,
763 [&](const QMediaContent& content)
764 {
765 qDebug() << "currentMediaChanged to: " << content.canonicalUrl().toString();
766 current_media = content;
767 promise.set_value(current_media);
768 // Make sure the promise is not fulfilled twice
769 QObject::disconnect(c);
770 });
771
772 wait_for_signal(future);
773}
774
775void tst_MediaPlaylist::waitTrackInserted(QMediaPlaylist *playlist)
776{
777 int index = 0;
778 std::promise<int> promise;
779 std::future<int> future{promise.get_future()};
780
781 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::mediaInserted,
782 [&](int start, int end)
783 {
784 qDebug() << "mediaInserted start: " << start << ", end: " << end;
785 index = end;
786 promise.set_value(index);
787 // Make sure the promise is not fulfilled twice
788 QObject::disconnect(c);
789 });
790
791 wait_for_signal(future);
792}
793
794void tst_MediaPlaylist::waitTrackRemoved(QMediaPlaylist *playlist)
795{
796 int index = 0;
797 std::promise<int> promise;
798 std::future<int> future{promise.get_future()};
799
800 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::mediaRemoved,
801 [&](int start, int end)
802 {
803 qDebug() << "mediaRemoved start: " << start << ", end: " << end;
804 index = end;
805 promise.set_value(index);
806 // Make sure the promise is not fulfilled twice
807 QObject::disconnect(c);
808 });
809
810 wait_for_signal(future);
811}
812
813void tst_MediaPlaylist::waitPlaybackModeChange(QMediaPlaylist *playlist,
814 const std::function<void()>& action)
815{
816 QMediaPlaylist::PlaybackMode current_mode;
817 std::promise<QMediaPlaylist::PlaybackMode> promise;
818 std::future<QMediaPlaylist::PlaybackMode> future{promise.get_future()};
819
820 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::playbackModeChanged,
821 [&](QMediaPlaylist::PlaybackMode mode)
822 {
823 qDebug() << "playbackModeChanged to: " << mode;
824 current_mode = mode;
825 promise.set_value(current_mode);
826 // Make sure the promise is not fulfilled twice
827 QObject::disconnect(c);
828 });
829
830 action();
831
832 wait_for_signal(future);
833}
834
835void tst_MediaPlaylist::waitCurrentIndexChange(QMediaPlaylist *playlist)
836{
837 int index = 0;
838 std::promise<int> promise;
839 std::future<int> future{promise.get_future()};
840
841 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::currentIndexChanged,
842 [&](int i)
843 {
844 qDebug() << "currentIndexChanged index: " << i;
845 index = i;
846 promise.set_value(index);
847 // Make sure the promise is not fulfilled twice
848 QObject::disconnect(c);
849 });
850
851 wait_for_signal(future);
852}
853
854void tst_MediaPlaylist::connectSignal(QMediaPlaylist *playlist, Signals signal)
855{
856 switch (signal)
857 {
858 case Signals::Unknown:
859 break;
860 case Signals::CurrentMediaChanged:
861 {
862 connect(playlist, &QMediaPlaylist::currentMediaChanged, [&](const QMediaContent& content)
863 {
864 (void) content;
865 qDebug() << "Pushing CurrentMediaChanged onto m_signalsDeque";
866 m_signalsDeque.push_back(signal);
867 });
868 break;
869 }
870 case Signals::MediaInserted:
871 {
872 connect(playlist, &QMediaPlaylist::mediaInserted, [&](int start, int end)
873 {
874 (void) start;
875 (void) end;
876 qDebug() << "Pushing MediaInserted onto m_signalsDeque";
877 m_signalsDeque.push_back(signal);
878 });
879 break;
880 }
881 case Signals::MediaRemoved:
882 {
883 connect(playlist, &QMediaPlaylist::mediaRemoved, [&](int index)
884 {
885 (void) index;
886 qDebug() << "Pushing MediaRemoved onto m_signalsDeque";
887 m_signalsDeque.push_back(signal);
888 });
889 break;
890 }
891 default:
892 qWarning() << "Unknown signal type, can't add to queue:" << signal;
893 }
894}
895
896QTEST_GUILESS_MAIN(tst_MediaPlaylist)
0897
=== added file 'tests/integration/playlists/tst_mediaplaylist.h'
--- tests/integration/playlists/tst_mediaplaylist.h 1970-01-01 00:00:00 +0000
+++ tests/integration/playlists/tst_mediaplaylist.h 2016-02-22 16:57:32 +0000
@@ -0,0 +1,110 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef TST_MEDIAPLAYLIST_H
18#define TST_MEDIAPLAYLIST_H
19
20#include <core/media/player.h>
21
22#include <deque>
23#include <future>
24#include <memory>
25
26#include <QMediaPlayer>
27#include <QMediaPlaylist>
28#include <QObject>
29
30class AalMediaPlaylistControl;
31class QMediaPlayer;
32
33class tst_MediaPlaylist : public QObject
34{
35 Q_OBJECT
36
37 AalMediaPlaylistControl *m_mediaPlaylistControl;
38
39public:
40 enum Signals {
41 Unknown,
42 CurrentMediaChanged,
43 MediaInserted,
44 MediaRemoved
45 };
46
47Q_SIGNALS:
48
49private Q_SLOTS:
50 // We want the setup to be run prior to every test case to
51 // ensure correct test isolation, see http://qt-project.org/doc/qt-5/qtest-overview.html.
52 void initTestCase();
53 void cleanupTestCase();
54
55 void init();
56
57 void constructDestroyRepeat();
58
59 void addTwoTracksAndVerify();
60 void insertTracksAtPositionAndVerify();
61 void moveTrackAndVerify();
62 void movePlayingTrackAndVerify();
63 void addListOfTracksAndVerify();
64 void addLargeListOfTracksAndVerify();
65 void addLargeListOfTracksAtOnceAndVerify();
66 void addTwoListsOfTracksAtOnceAndVerify();
67
68 void goToNextTrack();
69 void goToPreviousTrack();
70 void verifyMedia();
71
72 void removeTrackAndVerify();
73 void removeCurrentNonPlayingTrackAndVerify();
74 void removeCurrentPlayingTrackAndVerify();
75 void removeLastCurrentPlayingTrackAndVerify();
76
77 void verifyCurrentIndex();
78 void verifyNextIndex();
79 void verifyPreviousIndex();
80
81 void verifyPlaybackModeCurrentItemInLoop();
82 void verifyPlaybackModeSequential();
83
84 void playReusePlayTrackList();
85
86private:
87 std::deque<Signals> m_signalsDeque;
88
89 template<typename R>
90 bool is_ready(std::future<R> const& f)
91 { return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }
92
93 template<typename R>
94 void wait_for_signal(std::future<R> const& f);
95
96 void waitTrackChange(QMediaPlaylist *playlist);
97 void waitTrackInserted(QMediaPlaylist *playlist);
98 void waitTrackRemoved(QMediaPlaylist *playlist);
99 void waitPlaybackModeChange(QMediaPlaylist *playlist,
100 const std::function<void()>& action);
101 void waitCurrentIndexChange(QMediaPlaylist *playlist);
102
103 // A generic way of getting a signal registered into m_signalsDeque without blocking
104 // which can be used to later check the order of signals that were emitted. Simply call
105 // this method for each signal that you'd like to check and it'll be pushed onto the deque
106 // when it's fired.
107 void connectSignal(QMediaPlaylist *playlist, Signals signal);
108};
109
110#endif // TST_MEDIAPLAYLIST_H
0111
=== removed directory 'tests/integration/testdata'
=== removed file 'tests/integration/testdata/Ubuntu.ogg'
1Binary files tests/integration/testdata/Ubuntu.ogg 2015-11-03 18:00:37 +0000 and tests/integration/testdata/Ubuntu.ogg 1970-01-01 00:00:00 +0000 differ112Binary files tests/integration/testdata/Ubuntu.ogg 2015-11-03 18:00:37 +0000 and tests/integration/testdata/Ubuntu.ogg 1970-01-01 00:00:00 +0000 differ
=== removed file 'tests/integration/testdata/testfile.mp4'
2Binary files tests/integration/testdata/testfile.mp4 2015-07-07 20:31:08 +0000 and tests/integration/testdata/testfile.mp4 1970-01-01 00:00:00 +0000 differ113Binary files tests/integration/testdata/testfile.mp4 2015-07-07 20:31:08 +0000 and tests/integration/testdata/testfile.mp4 1970-01-01 00:00:00 +0000 differ
=== removed file 'tests/integration/testdata/testfile.ogg'
3Binary files tests/integration/testdata/testfile.ogg 2015-07-07 20:31:08 +0000 and tests/integration/testdata/testfile.ogg 1970-01-01 00:00:00 +0000 differ114Binary files tests/integration/testdata/testfile.ogg 2015-07-07 20:31:08 +0000 and tests/integration/testdata/testfile.ogg 1970-01-01 00:00:00 +0000 differ
=== removed file 'tests/integration/testdata/testfile1.ogg'
4Binary files tests/integration/testdata/testfile1.ogg 2015-10-09 20:06:40 +0000 and tests/integration/testdata/testfile1.ogg 1970-01-01 00:00:00 +0000 differ115Binary files tests/integration/testdata/testfile1.ogg 2015-10-09 20:06:40 +0000 and tests/integration/testdata/testfile1.ogg 1970-01-01 00:00:00 +0000 differ
=== removed file 'tests/integration/testdata/testfile2.ogg'
5Binary files tests/integration/testdata/testfile2.ogg 2015-10-09 20:06:40 +0000 and tests/integration/testdata/testfile2.ogg 1970-01-01 00:00:00 +0000 differ116Binary files tests/integration/testdata/testfile2.ogg 2015-10-09 20:06:40 +0000 and tests/integration/testdata/testfile2.ogg 1970-01-01 00:00:00 +0000 differ
=== removed file 'tests/integration/testdata/testfile3.ogg'
6Binary files tests/integration/testdata/testfile3.ogg 2015-10-09 20:06:40 +0000 and tests/integration/testdata/testfile3.ogg 1970-01-01 00:00:00 +0000 differ117Binary files tests/integration/testdata/testfile3.ogg 2015-10-09 20:06:40 +0000 and tests/integration/testdata/testfile3.ogg 1970-01-01 00:00:00 +0000 differ
=== removed file 'tests/integration/testdata/testfile4.ogg'
7Binary files tests/integration/testdata/testfile4.ogg 2015-10-09 20:06:40 +0000 and tests/integration/testdata/testfile4.ogg 1970-01-01 00:00:00 +0000 differ118Binary files tests/integration/testdata/testfile4.ogg 2015-10-09 20:06:40 +0000 and tests/integration/testdata/testfile4.ogg 1970-01-01 00:00:00 +0000 differ
=== removed file 'tests/integration/tst_mediaplaylist.cpp'
--- tests/integration/tst_mediaplaylist.cpp 2015-11-17 22:25:36 +0000
+++ tests/integration/tst_mediaplaylist.cpp 1970-01-01 00:00:00 +0000
@@ -1,896 +0,0 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "tst_mediaplaylist.h"
18#include "aalutility.h"
19
20#include <thread>
21#include <unistd.h>
22
23#include <QMediaPlayer>
24#include <QMediaPlaylist>
25
26#include <QtTest/QtTest>
27
28void tst_MediaPlaylist::initTestCase()
29{
30}
31
32void tst_MediaPlaylist::cleanupTestCase()
33{
34}
35
36void tst_MediaPlaylist::init()
37{
38 // NOTE: This sleep is currently needed in order to give media-hub a bit of time
39 // between our different tests to cleanup and come back in a state where it can
40 // respond to our requests.
41 sleep(1);
42}
43
44void tst_MediaPlaylist::constructDestroyRepeat()
45{
46 for (int i=0; i<25; i++)
47 {
48 QMediaPlayer *player = new QMediaPlayer;
49 QMediaPlaylist *playlist = new QMediaPlaylist;
50 player->setPlaylist(playlist);
51
52 delete playlist;
53 delete player;
54 }
55}
56
57void tst_MediaPlaylist::addTwoTracksAndVerify()
58{
59 QMediaPlayer *player = new QMediaPlayer;
60 QMediaPlaylist *playlist = new QMediaPlaylist;
61 player->setPlaylist(playlist);
62
63 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
64 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
65
66 QCOMPARE(playlist->mediaCount(), 2);
67
68 delete playlist;
69 delete player;
70}
71
72void tst_MediaPlaylist::insertTracksAtPositionAndVerify()
73{
74 QMediaPlayer *player = new QMediaPlayer;
75 QMediaPlaylist *playlist = new QMediaPlaylist;
76 player->setPlaylist(playlist);
77
78 QElapsedTimer timer;
79 timer.start();
80 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
81 waitTrackInserted(playlist);
82 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
83 waitTrackInserted(playlist);
84 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
85 waitTrackInserted(playlist);
86 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
87 waitTrackInserted(playlist);
88 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
89 waitTrackInserted(playlist);
90 qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
91
92 QCOMPARE(playlist->mediaCount(), 5);
93
94 const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
95 playlist->insertMedia(2, insertedTrack);
96 waitTrackInserted(playlist);
97
98 qDebug() << "playlist->media(2):" << playlist->media(2).canonicalUrl();
99 qDebug() << "insertedTrack:" << insertedTrack.canonicalUrl();
100 QCOMPARE(playlist->media(2), insertedTrack);
101
102 delete playlist;
103 delete player;
104}
105
106void tst_MediaPlaylist::moveTrackAndVerify()
107{
108 QMediaPlayer *player = new QMediaPlayer;
109 QMediaPlaylist *playlist = new QMediaPlaylist;
110 player->setPlaylist(playlist);
111
112 QElapsedTimer timer;
113 timer.start();
114 QList<QMediaContent> content;
115 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
116 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
117 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
118 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
119 const QMediaContent newLastTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
120 content.push_back(newLastTrack);
121 const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
122 content.push_back(insertedTrack);
123 playlist->addMedia(content);
124 waitTrackInserted(playlist);
125 qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
126
127 QCOMPARE(playlist->mediaCount(), 6);
128
129 connectSignal(playlist, Signals::MediaRemoved);
130 connectSignal(playlist, Signals::MediaInserted);
131 playlist->moveMedia(5, 2);
132
133 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
134 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
135 QCOMPARE(playlist->mediaCount(), 6);
136
137 delete playlist;
138 delete player;
139}
140
141void tst_MediaPlaylist::movePlayingTrackAndVerify()
142{
143 QMediaPlayer *player = new QMediaPlayer;
144 QMediaPlaylist *playlist = new QMediaPlaylist;
145 player->setPlaylist(playlist);
146
147 QElapsedTimer timer;
148 timer.start();
149 QList<QMediaContent> content;
150 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
151 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
152 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
153 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
154 const QMediaContent newLastTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
155 content.push_back(newLastTrack);
156 const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/Ubuntu.ogg")));
157 content.push_back(insertedTrack);
158 playlist->addMedia(content);
159 waitTrackInserted(playlist);
160 qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
161
162 playlist->setCurrentIndex(5);
163 waitCurrentIndexChange(playlist);
164 QCOMPARE(playlist->currentIndex(), 5);
165
166 player->play();
167
168 QCOMPARE(playlist->mediaCount(), 6);
169
170 sleep(2);
171
172 connectSignal(playlist, Signals::MediaRemoved);
173 connectSignal(playlist, Signals::MediaInserted);
174 playlist->moveMedia(5, 2);
175
176 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
177 qDebug() << "Verifying the presence of MediaInserted signal in deque";
178 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
179 QCOMPARE(playlist->mediaCount(), 6);
180
181 waitCurrentIndexChange(playlist);
182
183 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
184 QCOMPARE(playlist->currentIndex(), 2);
185
186 delete playlist;
187 delete player;
188}
189
190void tst_MediaPlaylist::addListOfTracksAndVerify()
191{
192 QMediaPlayer *player = new QMediaPlayer;
193 QMediaPlaylist *playlist = new QMediaPlaylist;
194 player->setPlaylist(playlist);
195
196 QList<QMediaContent> content;
197 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
198 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
199
200 playlist->addMedia(content);
201
202 QCOMPARE(playlist->mediaCount(), 2);
203
204 delete playlist;
205 delete player;
206}
207
208void tst_MediaPlaylist::addLargeListOfTracksAndVerify()
209{
210 QMediaPlayer *player = new QMediaPlayer;
211 QMediaPlaylist *playlist = new QMediaPlaylist;
212 player->setPlaylist(playlist);
213
214 // Total number of tracks added will be iterations * 5
215 const uint16_t iterations = 20;
216 QElapsedTimer timer;
217 timer.start();
218 for (uint16_t i=0; i<iterations; i++)
219 {
220 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
221 waitTrackInserted(playlist);
222 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
223 waitTrackInserted(playlist);
224 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
225 waitTrackInserted(playlist);
226 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
227 waitTrackInserted(playlist);
228 playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
229 waitTrackInserted(playlist);
230 }
231 qDebug() << "** addMedia loop took" << timer.elapsed() << "milliseconds";
232
233 QCOMPARE(playlist->mediaCount(), iterations * 5);
234
235 delete playlist;
236 delete player;
237}
238
239void tst_MediaPlaylist::addLargeListOfTracksAtOnceAndVerify()
240{
241 QMediaPlayer *player = new QMediaPlayer;
242 QMediaPlaylist *playlist = new QMediaPlaylist;
243 player->setPlaylist(playlist);
244
245 QList<QMediaContent> content;
246 int i;
247 for (i=0; i<20; i++)
248 {
249 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
250 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
251 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
252 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
253 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
254 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
255 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
256 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
257 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
258 content.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
259 }
260
261 QElapsedTimer timer;
262 timer.start();
263 playlist->addMedia(content);
264 qDebug() << "** addMedia(QList) took" << timer.elapsed() << "milliseconds";
265
266 waitTrackInserted(playlist);
267 QCOMPARE(playlist->mediaCount(), i * 10);
268
269 delete playlist;
270 delete player;
271}
272
273void tst_MediaPlaylist::addTwoListsOfTracksAtOnceAndVerify()
274{
275 QMediaPlayer *player = new QMediaPlayer;
276 QMediaPlaylist *playlist = new QMediaPlaylist;
277 player->setPlaylist(playlist);
278
279 QList<QMediaContent> content1;
280 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
281 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
282 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
283 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
284 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
285 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
286 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
287 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
288 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
289 content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
290
291 QList<QMediaContent> content2;
292 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
293 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
294 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
295 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
296 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
297 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
298 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
299 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
300 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
301 content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
302
303 QElapsedTimer timer;
304 timer.start();
305 playlist->addMedia(content1);
306 qDebug() << "** First list addMedia(QList) took" << timer.elapsed() << "milliseconds";
307
308 waitTrackInserted(playlist);
309 QCOMPARE(playlist->mediaCount(), 10);
310
311 timer.invalidate();
312 timer.start();
313 playlist->addMedia(content2);
314 qDebug() << "** Second list addMedia(QList) took" << timer.elapsed() << "milliseconds";
315
316 waitTrackInserted(playlist);
317 QCOMPARE(playlist->mediaCount(), 20);
318
319 delete playlist;
320 delete player;
321}
322
323void tst_MediaPlaylist::goToNextTrack()
324{
325 QMediaPlayer *player = new QMediaPlayer;
326 QMediaPlaylist *playlist = new QMediaPlaylist;
327 player->setPlaylist(playlist);
328
329 const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
330 const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
331 qDebug() << "audio URL: " << audio.toString();
332 qDebug() << "video URL: " << video.toString();
333 playlist->addMedia(audio);
334 playlist->addMedia(video);
335
336 QCOMPARE(playlist->mediaCount(), 2);
337
338 player->play();
339
340 QCoreApplication::processEvents();
341
342 const QUrl audioToVerify(playlist->currentMedia().canonicalUrl());
343 QCOMPARE(audioToVerify, audio);
344
345 playlist->next();
346
347 QCoreApplication::processEvents();
348
349 const QUrl videoToVerify(playlist->currentMedia().canonicalUrl());
350 QCOMPARE(videoToVerify, video);
351
352 delete playlist;
353 delete player;
354}
355
356void tst_MediaPlaylist::goToPreviousTrack()
357{
358 QMediaPlayer *player = new QMediaPlayer;
359 QMediaPlaylist *playlist = new QMediaPlaylist;
360 player->setPlaylist(playlist);
361
362 const QUrl audio1(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
363 const QUrl audio2(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
364 playlist->addMedia(audio1);
365 playlist->addMedia(audio2);
366
367 QCOMPARE(playlist->mediaCount(), 2);
368 playlist->setCurrentIndex(1);
369
370 player->play();
371
372 QCoreApplication::processEvents();
373
374 const QUrl audio2ToVerify(playlist->currentMedia().canonicalUrl());
375 QCOMPARE(audio2ToVerify, audio2);
376
377 playlist->previous();
378
379 QCoreApplication::processEvents();
380
381 const QUrl audio1ToVerify(playlist->currentMedia().canonicalUrl());
382 QCOMPARE(audio2ToVerify, audio1);
383 QCOMPARE(playlist->currentIndex(), 0);
384
385 delete playlist;
386 delete player;
387}
388
389void tst_MediaPlaylist::verifyMedia()
390{
391 QMediaPlayer *player = new QMediaPlayer;
392 QMediaPlaylist *playlist = new QMediaPlaylist;
393 player->setPlaylist(playlist);
394
395 const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
396 const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
397 qDebug() << "audio URL: " << audio.toString();
398 qDebug() << "video URL: " << video.toString();
399 playlist->addMedia(audio);
400 playlist->addMedia(video);
401
402 QCOMPARE(playlist->mediaCount(), 2);
403
404 const QUrl audioToVerify(playlist->media(0).canonicalUrl());
405 QCOMPARE(audioToVerify, audio);
406
407 const QUrl videoToVerify(playlist->media(1).canonicalUrl());
408 QCOMPARE(videoToVerify, video);
409
410 delete playlist;
411 delete player;
412}
413
414void tst_MediaPlaylist::removeTrackAndVerify()
415{
416 QMediaPlayer *player = new QMediaPlayer;
417 QMediaPlaylist *playlist = new QMediaPlaylist;
418 player->setPlaylist(playlist);
419
420 playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
421 const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
422 playlist->addMedia(video);
423
424 waitTrackInserted(playlist);
425 QCOMPARE(playlist->mediaCount(), 2);
426
427 playlist->removeMedia(0);
428
429 QCOMPARE(playlist->mediaCount(), 1);
430
431 const QUrl videoToVerify(playlist->media(0).canonicalUrl());
432 QCOMPARE(videoToVerify, video);
433
434 delete playlist;
435 delete player;
436}
437
438void tst_MediaPlaylist::removeCurrentNonPlayingTrackAndVerify()
439{
440 QMediaPlayer *player = new QMediaPlayer;
441 QMediaPlaylist *playlist = new QMediaPlaylist;
442 player->setPlaylist(playlist);
443
444 QList<QMediaContent> content1;
445 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
446 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
447 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
448 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
449 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
450 playlist->addMedia(content1);
451 const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
452 playlist->addMedia(track);
453
454 waitTrackInserted(playlist);
455 QCOMPARE(playlist->mediaCount(), 6);
456
457 playlist->setCurrentIndex(2);
458 // Wait for the currentMediaChanged signal to be emited
459 waitTrackChange(playlist);
460 // We should not be automatically playing
461 QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
462 QCOMPARE(playlist->currentIndex(), 2);
463
464 playlist->removeMedia(2);
465
466 // We should still not be playing
467 QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
468
469 QCOMPARE(playlist->mediaCount(), 5);
470
471 const QUrl trackToVerify(playlist->media(4).canonicalUrl());
472 QCOMPARE(trackToVerify, track);
473
474 delete playlist;
475 delete player;
476}
477
478void tst_MediaPlaylist::removeCurrentPlayingTrackAndVerify()
479{
480 QMediaPlayer *player = new QMediaPlayer;
481 QMediaPlaylist *playlist = new QMediaPlaylist;
482 player->setPlaylist(playlist);
483
484 QList<QMediaContent> content1;
485 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
486 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
487 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
488 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
489 content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
490 playlist->addMedia(content1);
491 const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
492 playlist->addMedia(track);
493
494 waitTrackInserted(playlist);
495 QCOMPARE(playlist->mediaCount(), 6);
496
497 player->play();
498
499 playlist->setCurrentIndex(2);
500 // Wait for the currentMediaChanged signal to be emited
501 waitTrackChange(playlist);
502 // We be playing
503 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
504 QCOMPARE(playlist->currentIndex(), 2);
505
506 playlist->removeMedia(2);
507
508 // We should still be playing
509 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
510
511 QCOMPARE(playlist->mediaCount(), 5);
512
513 const QUrl trackToVerify(playlist->media(4).canonicalUrl());
514 QCOMPARE(trackToVerify, track);
515
516 delete playlist;
517 delete player;
518}
519
520void tst_MediaPlaylist::removeLastCurrentPlayingTrackAndVerify()
521{
522 QMediaPlayer *player = new QMediaPlayer;
523 QMediaPlaylist *playlist = new QMediaPlaylist;
524 player->setPlaylist(playlist);
525
526 const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
527 playlist->addMedia(track);
528
529 waitTrackInserted(playlist);
530 QCOMPARE(playlist->mediaCount(), 1);
531
532 player->play();
533
534 playlist->setCurrentIndex(0);
535 qDebug() << "Waiting for playback status to change to playing";
536 // Wait for the currentMediaChanged signal to be emited
537 waitTrackChange(playlist);
538 // We be playing
539 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
540
541 qDebug() << "Removing track index 0";
542 playlist->removeMedia(0);
543
544 waitTrackRemoved(playlist);
545 // We should no longer be playing
546 QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
547
548 QCOMPARE(playlist->mediaCount(), 0);
549
550 delete playlist;
551 delete player;
552}
553
554void tst_MediaPlaylist::verifyCurrentIndex()
555{
556 QMediaPlayer *player = new QMediaPlayer;
557 QMediaPlaylist *playlist = new QMediaPlaylist;
558 player->setPlaylist(playlist);
559
560 QList<QMediaContent> content;
561 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
562 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
563 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
564 playlist->addMedia(content);
565
566 waitTrackInserted(playlist);
567 QCOMPARE(playlist->mediaCount(), 3);
568
569 qDebug() << "Setting current index to be 1";
570 playlist->setCurrentIndex(1);
571
572 // Wait for the currentMediaChanged signal to be emited
573 waitTrackChange(playlist);
574
575 qDebug() << "Checking if current index is 1";
576 QCOMPARE(playlist->currentIndex(), 1);
577
578 delete playlist;
579 delete player;
580}
581
582void tst_MediaPlaylist::verifyNextIndex()
583{
584 QMediaPlayer *player = new QMediaPlayer;
585 QMediaPlaylist *playlist = new QMediaPlaylist;
586 player->setPlaylist(playlist);
587
588 QList<QMediaContent> content;
589 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
590 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
591 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
592 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
593 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
594 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
595 playlist->addMedia(content);
596
597 waitTrackInserted(playlist);
598 QCOMPARE(playlist->mediaCount(), 6);
599
600 QCOMPARE(playlist->nextIndex(1), 1);
601 QCOMPARE(playlist->nextIndex(4), 4);
602 QCOMPARE(playlist->nextIndex(6), 0);
603 QCOMPARE(playlist->nextIndex(7), 1);
604 QCOMPARE(playlist->nextIndex(11), 5);
605
606 delete playlist;
607 delete player;
608}
609
610void tst_MediaPlaylist::verifyPreviousIndex()
611{
612 QMediaPlayer *player = new QMediaPlayer;
613 QMediaPlaylist *playlist = new QMediaPlaylist;
614 player->setPlaylist(playlist);
615
616 QList<QMediaContent> content;
617 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
618 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
619 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
620 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
621 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
622 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
623 playlist->addMedia(content);
624
625 waitTrackInserted(playlist);
626 QCOMPARE(playlist->mediaCount(), 6);
627
628 QCOMPARE(playlist->previousIndex(1), 5);
629 QCOMPARE(playlist->previousIndex(4), 2);
630 QCOMPARE(playlist->previousIndex(6), 0);
631 QCOMPARE(playlist->previousIndex(11), 1);
632 QCOMPARE(playlist->previousIndex(21), 3);
633 QCOMPARE(playlist->previousIndex(19), 5);
634
635 delete playlist;
636 delete player;
637}
638
639void tst_MediaPlaylist::verifyPlaybackModeCurrentItemInLoop()
640{
641 QMediaPlayer *player = new QMediaPlayer;
642 QMediaPlaylist *playlist = new QMediaPlaylist;
643 player->setPlaylist(playlist);
644
645 connectSignal(playlist, Signals::MediaInserted);
646
647 QList<QMediaContent> content;
648 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
649 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
650 playlist->addMedia(content);
651
652 // Wait until the first track is set as the current one
653 waitTrackChange(playlist);
654 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
655 QCOMPARE(playlist->mediaCount(), 2);
656
657 waitPlaybackModeChange(playlist, [playlist]()
658 {
659 playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
660 });
661
662 player->play();
663
664 // Wait for the currentMediaChanged signal to be emited
665 waitTrackChange(playlist);
666
667 QCOMPARE(playlist->currentIndex(), 0);
668
669 delete playlist;
670 delete player;
671}
672
673void tst_MediaPlaylist::verifyPlaybackModeSequential()
674{
675 QMediaPlayer *player = new QMediaPlayer;
676 QMediaPlaylist *playlist = new QMediaPlaylist;
677 player->setPlaylist(playlist);
678
679 connectSignal(playlist, Signals::MediaInserted);
680
681 QList<QMediaContent> content;
682 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
683 content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
684 playlist->addMedia(content);
685
686 // Wait until the first track is set as the current one
687 waitTrackChange(playlist);
688 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
689 QCOMPARE(playlist->mediaCount(), 2);
690
691 waitPlaybackModeChange(playlist, [playlist]()
692 {
693 playlist->setPlaybackMode(QMediaPlaylist::Sequential);
694 });
695
696 player->play();
697
698 // Wait until the second track is selected
699 waitTrackChange(playlist);
700
701 QCOMPARE(playlist->currentIndex(), 1);
702
703 delete playlist;
704 delete player;
705}
706
707void tst_MediaPlaylist::playReusePlayTrackList()
708{
709 QMediaPlayer *player = new QMediaPlayer;
710 QMediaPlaylist *playlist = new QMediaPlaylist;
711 player->setPlaylist(playlist);
712
713 const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
714 const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
715
716 for (int i = 0; i < 5; ++i) {
717 playlist->addMedia(audio);
718 waitTrackInserted(playlist);
719 playlist->addMedia(video);
720 waitTrackInserted(playlist);
721 playlist->addMedia(audio);
722 waitTrackInserted(playlist);
723 QCOMPARE(playlist->mediaCount(), 3);
724
725 player->play();
726
727 const QUrl audioToVerify(playlist->currentMedia().canonicalUrl());
728 QCOMPARE(audioToVerify, audio);
729
730 player->stop();
731
732 connectSignal(playlist, Signals::MediaRemoved);
733 playlist->clear();
734
735 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
736
737 QCOMPARE(playlist->mediaCount(), 0);
738 }
739
740 delete playlist;
741 delete player;
742}
743
744template<typename R>
745void tst_MediaPlaylist::wait_for_signal(std::future<R> const& f)
746{
747 while (!is_ready<R>(f))
748 {
749 // Make sure we don't block the main QEventLoop, which
750 // would hinder receiving the currentMediaChanged event above
751 QCoreApplication::processEvents();
752 std::this_thread::yield();
753 }
754}
755
756void tst_MediaPlaylist::waitTrackChange(QMediaPlaylist *playlist)
757{
758 QMediaContent current_media;
759 std::promise<QMediaContent> promise;
760 std::future<QMediaContent> future{promise.get_future()};
761
762 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::currentMediaChanged,
763 [&](const QMediaContent& content)
764 {
765 qDebug() << "currentMediaChanged to: " << content.canonicalUrl().toString();
766 current_media = content;
767 promise.set_value(current_media);
768 // Make sure the promise is not fulfilled twice
769 QObject::disconnect(c);
770 });
771
772 wait_for_signal(future);
773}
774
775void tst_MediaPlaylist::waitTrackInserted(QMediaPlaylist *playlist)
776{
777 int index = 0;
778 std::promise<int> promise;
779 std::future<int> future{promise.get_future()};
780
781 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::mediaInserted,
782 [&](int start, int end)
783 {
784 qDebug() << "mediaInserted start: " << start << ", end: " << end;
785 index = end;
786 promise.set_value(index);
787 // Make sure the promise is not fulfilled twice
788 QObject::disconnect(c);
789 });
790
791 wait_for_signal(future);
792}
793
794void tst_MediaPlaylist::waitTrackRemoved(QMediaPlaylist *playlist)
795{
796 int index = 0;
797 std::promise<int> promise;
798 std::future<int> future{promise.get_future()};
799
800 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::mediaRemoved,
801 [&](int start, int end)
802 {
803 qDebug() << "mediaRemoved start: " << start << ", end: " << end;
804 index = end;
805 promise.set_value(index);
806 // Make sure the promise is not fulfilled twice
807 QObject::disconnect(c);
808 });
809
810 wait_for_signal(future);
811}
812
813void tst_MediaPlaylist::waitPlaybackModeChange(QMediaPlaylist *playlist,
814 const std::function<void()>& action)
815{
816 QMediaPlaylist::PlaybackMode current_mode;
817 std::promise<QMediaPlaylist::PlaybackMode> promise;
818 std::future<QMediaPlaylist::PlaybackMode> future{promise.get_future()};
819
820 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::playbackModeChanged,
821 [&](QMediaPlaylist::PlaybackMode mode)
822 {
823 qDebug() << "playbackModeChanged to: " << mode;
824 current_mode = mode;
825 promise.set_value(current_mode);
826 // Make sure the promise is not fulfilled twice
827 QObject::disconnect(c);
828 });
829
830 action();
831
832 wait_for_signal(future);
833}
834
835void tst_MediaPlaylist::waitCurrentIndexChange(QMediaPlaylist *playlist)
836{
837 int index = 0;
838 std::promise<int> promise;
839 std::future<int> future{promise.get_future()};
840
841 QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::currentIndexChanged,
842 [&](int i)
843 {
844 qDebug() << "currentIndexChanged index: " << i;
845 index = i;
846 promise.set_value(index);
847 // Make sure the promise is not fulfilled twice
848 QObject::disconnect(c);
849 });
850
851 wait_for_signal(future);
852}
853
854void tst_MediaPlaylist::connectSignal(QMediaPlaylist *playlist, Signals signal)
855{
856 switch (signal)
857 {
858 case Signals::Unknown:
859 break;
860 case Signals::CurrentMediaChanged:
861 {
862 connect(playlist, &QMediaPlaylist::currentMediaChanged, [&](const QMediaContent& content)
863 {
864 (void) content;
865 qDebug() << "Pushing CurrentMediaChanged onto m_signalsDeque";
866 m_signalsDeque.push_back(signal);
867 });
868 break;
869 }
870 case Signals::MediaInserted:
871 {
872 connect(playlist, &QMediaPlaylist::mediaInserted, [&](int start, int end)
873 {
874 (void) start;
875 (void) end;
876 qDebug() << "Pushing MediaInserted onto m_signalsDeque";
877 m_signalsDeque.push_back(signal);
878 });
879 break;
880 }
881 case Signals::MediaRemoved:
882 {
883 connect(playlist, &QMediaPlaylist::mediaRemoved, [&](int index)
884 {
885 (void) index;
886 qDebug() << "Pushing MediaRemoved onto m_signalsDeque";
887 m_signalsDeque.push_back(signal);
888 });
889 break;
890 }
891 default:
892 qWarning() << "Unknown signal type, can't add to queue:" << signal;
893 }
894}
895
896QTEST_GUILESS_MAIN(tst_MediaPlaylist)
8970
=== removed file 'tests/integration/tst_mediaplaylist.h'
--- tests/integration/tst_mediaplaylist.h 2015-11-17 22:25:36 +0000
+++ tests/integration/tst_mediaplaylist.h 1970-01-01 00:00:00 +0000
@@ -1,110 +0,0 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef TST_MEDIAPLAYLIST_H
18#define TST_MEDIAPLAYLIST_H
19
20#include <core/media/player.h>
21
22#include <deque>
23#include <future>
24#include <memory>
25
26#include <QMediaPlayer>
27#include <QMediaPlaylist>
28#include <QObject>
29
30class AalMediaPlaylistControl;
31class QMediaPlayer;
32
33class tst_MediaPlaylist : public QObject
34{
35 Q_OBJECT
36
37 AalMediaPlaylistControl *m_mediaPlaylistControl;
38
39public:
40 enum Signals {
41 Unknown,
42 CurrentMediaChanged,
43 MediaInserted,
44 MediaRemoved
45 };
46
47Q_SIGNALS:
48
49private Q_SLOTS:
50 // We want the setup to be run prior to every test case to
51 // ensure correct test isolation, see http://qt-project.org/doc/qt-5/qtest-overview.html.
52 void initTestCase();
53 void cleanupTestCase();
54
55 void init();
56
57 void constructDestroyRepeat();
58
59 void addTwoTracksAndVerify();
60 void insertTracksAtPositionAndVerify();
61 void moveTrackAndVerify();
62 void movePlayingTrackAndVerify();
63 void addListOfTracksAndVerify();
64 void addLargeListOfTracksAndVerify();
65 void addLargeListOfTracksAtOnceAndVerify();
66 void addTwoListsOfTracksAtOnceAndVerify();
67
68 void goToNextTrack();
69 void goToPreviousTrack();
70 void verifyMedia();
71
72 void removeTrackAndVerify();
73 void removeCurrentNonPlayingTrackAndVerify();
74 void removeCurrentPlayingTrackAndVerify();
75 void removeLastCurrentPlayingTrackAndVerify();
76
77 void verifyCurrentIndex();
78 void verifyNextIndex();
79 void verifyPreviousIndex();
80
81 void verifyPlaybackModeCurrentItemInLoop();
82 void verifyPlaybackModeSequential();
83
84 void playReusePlayTrackList();
85
86private:
87 std::deque<Signals> m_signalsDeque;
88
89 template<typename R>
90 bool is_ready(std::future<R> const& f)
91 { return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }
92
93 template<typename R>
94 void wait_for_signal(std::future<R> const& f);
95
96 void waitTrackChange(QMediaPlaylist *playlist);
97 void waitTrackInserted(QMediaPlaylist *playlist);
98 void waitTrackRemoved(QMediaPlaylist *playlist);
99 void waitPlaybackModeChange(QMediaPlaylist *playlist,
100 const std::function<void()>& action);
101 void waitCurrentIndexChange(QMediaPlaylist *playlist);
102
103 // A generic way of getting a signal registered into m_signalsDeque without blocking
104 // which can be used to later check the order of signals that were emitted. Simply call
105 // this method for each signal that you'd like to check and it'll be pushed onto the deque
106 // when it's fired.
107 void connectSignal(QMediaPlaylist *playlist, Signals signal);
108};
109
110#endif // TST_MEDIAPLAYLIST_H
1110
=== added directory 'tests/integration/uris'
=== added file 'tests/integration/uris/generate_test_files.sh'
--- tests/integration/uris/generate_test_files.sh 1970-01-01 00:00:00 +0000
+++ tests/integration/uris/generate_test_files.sh 2016-02-22 16:57:32 +0000
@@ -0,0 +1,25 @@
1#!/bin/bash
2
3WORKING_DIR=/tmp/qtubuntu-media
4BASE_FILE=$1/testdata/Ubuntu.ogg
5
6mkdir $WORKING_DIR
7
8echo "WORKING_DIR: $WORKING_DIR"
9echo "BASE_FILE: $BASE_FILE"
10
11# Creates several files with a single character filename that starts
12# at ASCII char #32 and ends with #126
13for i in {32..127} # from 'Space' to '~'
14do
15 # skip '"', '%', '<', '>', '.', 'DEL'
16 if [ $i -eq 127 ]
17 then
18 continue
19 else
20 chr=$(printf \\$(printf '%03o' $i))
21
22 echo "Creating file $chr.ogg from $BASE_FILE" > "$WORKING_DIR/log.txt"
23 cp $BASE_FILE "$WORKING_DIR/track$chr.ogg"
24 fi
25done
026
=== added file 'tests/integration/uris/remove_test_files.sh'
--- tests/integration/uris/remove_test_files.sh 1970-01-01 00:00:00 +0000
+++ tests/integration/uris/remove_test_files.sh 2016-02-22 16:57:32 +0000
@@ -0,0 +1,7 @@
1#!/bin/bash
2
3WORKING_DIR=/tmp/qtubuntu-media
4
5if [ -d "$WORKING_DIR" ]; then
6 rm -r $WORKING_DIR
7fi
08
=== added directory 'tests/integration/uris/testdata'
=== added file 'tests/integration/uris/testdata/Ubuntu.ogg'
1Binary files tests/integration/uris/testdata/Ubuntu.ogg 1970-01-01 00:00:00 +0000 and tests/integration/uris/testdata/Ubuntu.ogg 2016-02-22 16:57:32 +0000 differ9Binary files tests/integration/uris/testdata/Ubuntu.ogg 1970-01-01 00:00:00 +0000 and tests/integration/uris/testdata/Ubuntu.ogg 2016-02-22 16:57:32 +0000 differ
=== added file 'tests/integration/uris/tst_mediauris.cpp'
--- tests/integration/uris/tst_mediauris.cpp 1970-01-01 00:00:00 +0000
+++ tests/integration/uris/tst_mediauris.cpp 2016-02-22 16:57:32 +0000
@@ -0,0 +1,116 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "tst_mediauris.h"
18
19#include <unistd.h>
20
21#include <QMediaPlayer>
22#include <QMediaPlaylist>
23#include <QProcess>
24
25#include <QtTest/QtTest>
26
27void tst_MediaUris::initTestCase()
28{
29 QProcess p;
30 qDebug() << "Current working dir:" << QDir::currentPath();
31 p.start("../../../../tests/integration/uris/generate_test_files.sh",
32 QStringList() << QString{QDir::currentPath() + "/../../../../tests/integration/uris"});
33 p.waitForFinished();
34 QVERIFY(p.exitStatus() == QProcess::NormalExit);
35 QVERIFY(p.exitCode() == 0);
36}
37
38void tst_MediaUris::cleanupTestCase()
39{
40 QProcess p;
41 p.start("../../../../tests/integration/uris/remove_test_files.sh");
42 p.waitForFinished();
43 QVERIFY(p.exitStatus() == QProcess::NormalExit);
44 QVERIFY(p.exitCode() == 0);
45}
46
47void tst_MediaUris::init()
48{
49 // NOTE: This sleep is currently needed in order to give media-hub a bit of time
50 // between our different tests to cleanup and come back in a state where it can
51 // respond to our requests.
52 sleep(1);
53}
54
55void tst_MediaUris::verifySpecialAsciiCharsCanPlaySetMedia()
56{
57 QDir generatedFilesDir("/tmp/qtubuntu-media");
58 QStringList mediaFiles = generatedFilesDir.entryList(QDir::NoDotAndDotDot | QDir::System
59 | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
60
61 qDebug() << "mediaFiles.size():" << mediaFiles.size();
62
63 QMediaPlayer *player = new QMediaPlayer;
64
65 for (const QString &file : mediaFiles)
66 {
67 const QString fullFileUri {"file://" + generatedFilesDir.absolutePath() + "/" + file};
68 const QMediaContent content {QUrl{fullFileUri}};
69 qDebug() << "Trying to play file:" << fullFileUri;
70 player->setMedia(content);
71
72 player->play();
73 sleep(1);
74 qDebug() << "player->error():" << player->error();
75 qDebug() << "player->mediaStatus():" << player->mediaStatus();
76 QVERIFY(player->mediaStatus() != QMediaPlayer::InvalidMedia);
77 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
78 player->stop();
79 }
80
81 delete player;
82}
83
84void tst_MediaUris::verifySpecialAsciiCharsCanPlayPlaylist()
85{
86 QDir generatedFilesDir("/tmp/qtubuntu-media");
87 QStringList mediaFiles = generatedFilesDir.entryList(QDir::NoDotAndDotDot | QDir::System
88 | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
89
90 qDebug() << "mediaFiles.size():" << mediaFiles.size();
91
92 QMediaPlayer *player = new QMediaPlayer;
93 QMediaPlaylist *playlist = new QMediaPlaylist;
94 player->setPlaylist(playlist);
95
96 for (const QString &file : mediaFiles)
97 {
98 QString fullFileUri {"file://" + generatedFilesDir.absolutePath() + "/" + file};
99 qDebug() << "Trying to play file:" << fullFileUri;
100 playlist->addMedia(QUrl(fullFileUri));
101
102 player->play();
103 sleep(1);
104 qDebug() << "player->error():" << player->error();
105 qDebug() << "player->mediaStatus():" << player->mediaStatus();
106 QVERIFY(player->mediaStatus() != QMediaPlayer::InvalidMedia);
107 QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
108 player->stop();
109 playlist->clear();
110 }
111
112 delete playlist;
113 delete player;
114}
115
116QTEST_GUILESS_MAIN(tst_MediaUris)
0117
=== added file 'tests/integration/uris/tst_mediauris.h'
--- tests/integration/uris/tst_mediauris.h 1970-01-01 00:00:00 +0000
+++ tests/integration/uris/tst_mediauris.h 2016-02-22 16:57:32 +0000
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef TST_MEDIAURIS_H
18#define TST_MEDIAURIS_H
19
20#include <core/media/player.h>
21
22#include <deque>
23#include <future>
24#include <memory>
25
26#include <QMediaPlayer>
27#include <QMediaPlaylist>
28#include <QObject>
29
30class AalMediaPlaylistControl;
31class QMediaPlayer;
32
33class tst_MediaUris : public QObject
34{
35 Q_OBJECT
36
37private Q_SLOTS:
38 // We want the setup to be run prior to every test case to
39 // ensure correct test isolation, see http://qt-project.org/doc/qt-5/qtest-overview.html.
40 void initTestCase();
41 void cleanupTestCase();
42
43 void init();
44
45 void verifySpecialAsciiCharsCanPlaySetMedia();
46 void verifySpecialAsciiCharsCanPlayPlaylist();
47
48private:
49};
50
51#endif // TST_MEDIAURIS_H
052
=== added file 'tests/integration/uris/uris.pro'
--- tests/integration/uris/uris.pro 1970-01-01 00:00:00 +0000
+++ tests/integration/uris/uris.pro 2016-02-22 16:57:32 +0000
@@ -0,0 +1,23 @@
1include(../../coverage.pri)
2
3CONFIG += testcase
4QMAKE_CXXFLAGS += -std=c++11
5DEFINES += QT_NO_KEYWORDS
6TARGET = tst_uris
7
8QT += core multimedia testlib
9
10QT_TESTCASE_BUILDDIR = .
11
12INCLUDEPATH += ../../src/aal \
13 /usr/include/qt5/QtMultimedia \
14
15HEADERS += \
16 tst_mediauris.h
17
18SOURCES += \
19 tst_mediauris.cpp \
20 ../../../src/aal/aalutility.cpp
21
22# media-hub is required to be running for these tests
23#system(/sbin/stop media-hub; /sbin/start media-hub)

Subscribers

People subscribed via source and target branches

to all changes: