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
1=== modified file 'README'
2--- README 2015-09-09 15:13:10 +0000
3+++ README 2016-02-22 16:57:32 +0000
4@@ -1,3 +1,10 @@
5+Integrations Tests:
6+-------------------
7+* Currently, the integration tests are disabled by default. To utilize them, you first need to
8+ uncomment the last line in tests/tests.pro (starts with "system"). Then from the build/ dir,
9+ run qmake -r .. followed by make. After it's done building, cd to each integration test's dir
10+ within build/ and manually run each test's binary.
11+
12 Coding Convention:
13 ------------------
14
15
16=== modified file 'src/aal/aalmediaplayerservice.cpp'
17--- src/aal/aalmediaplayerservice.cpp 2016-01-14 19:56:59 +0000
18+++ src/aal/aalmediaplayerservice.cpp 2016-02-22 16:57:32 +0000
19@@ -312,14 +312,19 @@
20 if (m_mediaPlaylistProvider && url.isEmpty())
21 m_mediaPlaylistProvider->clear();
22
23- const media::Track::UriType uri(url.url().toStdString());
24 if (m_mediaPlaylistProvider == nullptr || m_mediaPlaylistProvider->mediaCount() == 0)
25 {
26 try {
27- m_hubPlayerSession->open_uri(uri);
28+ m_hubPlayerSession->open_uri(url.toString().toStdString());
29 }
30 catch (const media::Player::Errors::InsufficientAppArmorPermissions &e) {
31 qWarning() << e.what();
32+ signalQMediaPlayerError(media::Player::Error::resource_error);
33+ return;
34+ }
35+ catch (const media::Player::Errors::UriNotFound &e) {
36+ qWarning() << e.what();
37+ signalQMediaPlayerError(media::Player::Error::resource_error);
38 return;
39 }
40 catch (const std::runtime_error &e) {
41@@ -631,10 +636,12 @@
42 case media::Player::Error::resource_error:
43 outError = QMediaPlayer::ResourceError;
44 outErrorStr = "A media resource couldn't be resolved.";
45+ m_mediaPlayerControl->setMediaStatus(QMediaPlayer::InvalidMedia);
46 break;
47 case media::Player::Error::format_error:
48 outError = QMediaPlayer::FormatError;
49 outErrorStr = "The media format type is not playable due to a missing codec.";
50+ m_mediaPlayerControl->setMediaStatus(QMediaPlayer::InvalidMedia);
51 break;
52 case media::Player::Error::network_error:
53 outError = QMediaPlayer::NetworkError;
54@@ -643,6 +650,7 @@
55 case media::Player::Error::access_denied_error:
56 outError = QMediaPlayer::AccessDeniedError;
57 outErrorStr = "Insufficient privileges to play that media.";
58+ m_mediaPlayerControl->setMediaStatus(QMediaPlayer::InvalidMedia);
59 break;
60 case media::Player::Error::service_missing_error:
61 outError = QMediaPlayer::ServiceMissingError;
62
63=== modified file 'src/aal/aalmediaplaylistprovider.cpp'
64--- src/aal/aalmediaplaylistprovider.cpp 2016-01-05 16:58:37 +0000
65+++ src/aal/aalmediaplaylistprovider.cpp 2016-02-22 16:57:32 +0000
66@@ -108,8 +108,8 @@
67 }
68
69 const QUrl url = content.canonicalUrl();
70- std::string urlStr = AalUtility::unescape_str(content);
71- if (url.scheme().isEmpty() and url.scheme() != "file")
72+ std::string urlStr = url.toString().toStdString();
73+ if (url.scheme().isEmpty())
74 urlStr = "file://" + urlStr;
75
76 static const bool make_current = false;
77@@ -123,11 +123,19 @@
78 }
79 catch (const media::TrackList::Errors::InsufficientPermissionsToAddTrack &e)
80 {
81- qWarning() << "Failed to add track '" << content.canonicalUrl().toString() << "' to playlist: " << e.what();
82+ qWarning() << "Failed to add track '" << content.canonicalUrl().toString()
83+ << "' to playlist:" << e.what();
84+ return false;
85+ }
86+ catch (const media::Player::Errors::UriNotFound &e)
87+ {
88+ qWarning() << "Failed to add track '" << content.canonicalUrl().toString()
89+ << "' to playlist:" << e.what();
90 return false;
91 }
92 catch (const std::runtime_error &e) {
93- qWarning() << "Failed to add track '" << content.canonicalUrl().toString() << "' to playlist: " << e.what();
94+ qWarning() << "Failed to add track '" << content.canonicalUrl().toString()
95+ << "' to playlist: " << e.what();
96 return false;
97 }
98
99@@ -149,9 +157,9 @@
100 media::TrackList::ContainerURI uris;
101 for (const auto mediaContent : contentList) {
102 #ifdef VERBOSE_DEBUG
103- qDebug() << "Adding track " << AalUtility::unescape(mediaContent).toString();
104+ qDebug() << "Adding track " << mediaContent.canonicalUrl().toString().toStdString();
105 #endif
106- uris.push_back(AalUtility::unescape_str(mediaContent));
107+ uris.push_back(mediaContent.canonicalUrl().toString().toStdString());
108 }
109
110 const media::Track::Id after_empty_track = media::TrackList::after_empty_track();
111@@ -165,6 +173,11 @@
112 qWarning() << "Failed to add" << contentList.size() << "tracks to playlist: " << e.what();
113 return false;
114 }
115+ catch (const media::Player::Errors::UriNotFound &e)
116+ {
117+ qWarning() << "Failed to add certain tracks to playlist: " << e.what();
118+ return false;
119+ }
120 catch (const std::runtime_error &e) {
121 qWarning() << "Failed to add" << contentList.size() << "tracks to playlist: " << e.what();
122 return false;
123@@ -186,7 +199,7 @@
124 }
125
126 const QUrl url = content.canonicalUrl();
127- std::string urlStr = AalUtility::unescape_str(content);
128+ std::string urlStr = url.toString().toStdString();
129 if (url.scheme().isEmpty() and url.scheme() != "file")
130 urlStr = "file://" + urlStr;
131
132@@ -212,11 +225,13 @@
133 }
134 catch (const media::TrackList::Errors::InsufficientPermissionsToAddTrack &e)
135 {
136- 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();
139 return false;
140 }
141 catch (const std::runtime_error &e) {
142- qWarning() << "Failed to add track '" << content.canonicalUrl().toString() << "' to playlist: " << e.what();
143+ qWarning() << "Failed to add track '" << content.canonicalUrl().toString()
144+ << "' to playlist: " << e.what();
145 return false;
146 }
147
148
149=== modified file 'tests/integration/integration.pro'
150--- tests/integration/integration.pro 2015-11-03 15:58:40 +0000
151+++ tests/integration/integration.pro 2016-02-22 16:57:32 +0000
152@@ -1,23 +1,6 @@
153-include(../../coverage.pri)
154-
155-CONFIG += testcase
156-QMAKE_CXXFLAGS += -std=c++11
157-DEFINES += QT_NO_KEYWORDS
158-TARGET = tst_integration
159-
160-QT += core multimedia testlib
161-
162-QT_TESTCASE_BUILDDIR = .
163-
164-INCLUDEPATH += ../../src/aal \
165- /usr/include/qt5/QtMultimedia \
166-
167-HEADERS += \
168- tst_mediaplaylist.h
169-
170-SOURCES += \
171- tst_mediaplaylist.cpp \
172- ../../src/aal/aalutility.cpp
173-
174-# media-hub is required to be running for these tests
175-#system(/sbin/stop media-hub; /sbin/start media-hub)
176+include(coverage.pri)
177+
178+TEMPLATE = subdirs
179+
180+SUBDIRS += uris
181+SUBDIRS += playlists
182
183=== added directory 'tests/integration/playlists'
184=== added file 'tests/integration/playlists/playlists.pro'
185--- tests/integration/playlists/playlists.pro 1970-01-01 00:00:00 +0000
186+++ tests/integration/playlists/playlists.pro 2016-02-22 16:57:32 +0000
187@@ -0,0 +1,25 @@
188+include(../../coverage.pri)
189+
190+CONFIG += testcase
191+QMAKE_CXXFLAGS += -std=c++11
192+DEFINES += QT_NO_KEYWORDS
193+TARGET = tst_playlists
194+
195+QT += core multimedia testlib
196+
197+QT_TESTCASE_BUILDDIR = .
198+
199+INCLUDEPATH += ../../src/aal \
200+ /usr/include/qt5/QtMultimedia \
201+
202+HEADERS += \
203+ tst_mediaplaylist.h
204+
205+SOURCES += \
206+ tst_mediaplaylist.cpp \
207+ ../../../src/aal/aalutility.cpp
208+
209+SUBDIRS += uris
210+
211+# media-hub is required to be running for these tests
212+#system(/sbin/stop media-hub; /sbin/start media-hub)
213
214=== added directory 'tests/integration/playlists/testdata'
215=== added file 'tests/integration/playlists/testdata/Ubuntu.ogg'
216Binary 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
217=== added file 'tests/integration/playlists/testdata/testfile.mp4'
218Binary 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
219=== added file 'tests/integration/playlists/testdata/testfile.ogg'
220Binary 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
221=== added file 'tests/integration/playlists/testdata/testfile1.ogg'
222Binary 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
223=== added file 'tests/integration/playlists/testdata/testfile2.ogg'
224Binary 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
225=== added file 'tests/integration/playlists/testdata/testfile3.ogg'
226Binary 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
227=== added file 'tests/integration/playlists/testdata/testfile4.ogg'
228Binary 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
229=== added file 'tests/integration/playlists/tst_mediaplaylist.cpp'
230--- tests/integration/playlists/tst_mediaplaylist.cpp 1970-01-01 00:00:00 +0000
231+++ tests/integration/playlists/tst_mediaplaylist.cpp 2016-02-22 16:57:32 +0000
232@@ -0,0 +1,896 @@
233+/*
234+ * Copyright (C) 2015 Canonical, Ltd.
235+ *
236+ * This program is free software; you can redistribute it and/or modify
237+ * it under the terms of the GNU Lesser General Public License as published by
238+ * the Free Software Foundation; version 3.
239+ *
240+ * This program is distributed in the hope that it will be useful,
241+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
242+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
243+ * GNU General Public License for more details.
244+ *
245+ * You should have received a copy of the GNU Lesser General Public License
246+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
247+ */
248+
249+#include "tst_mediaplaylist.h"
250+#include "../../../src/aal/aalutility.h"
251+
252+#include <thread>
253+#include <unistd.h>
254+
255+#include <QMediaPlayer>
256+#include <QMediaPlaylist>
257+
258+#include <QtTest/QtTest>
259+
260+void tst_MediaPlaylist::initTestCase()
261+{
262+}
263+
264+void tst_MediaPlaylist::cleanupTestCase()
265+{
266+}
267+
268+void tst_MediaPlaylist::init()
269+{
270+ // NOTE: This sleep is currently needed in order to give media-hub a bit of time
271+ // between our different tests to cleanup and come back in a state where it can
272+ // respond to our requests.
273+ sleep(1);
274+}
275+
276+void tst_MediaPlaylist::constructDestroyRepeat()
277+{
278+ for (int i=0; i<25; i++)
279+ {
280+ QMediaPlayer *player = new QMediaPlayer;
281+ QMediaPlaylist *playlist = new QMediaPlaylist;
282+ player->setPlaylist(playlist);
283+
284+ delete playlist;
285+ delete player;
286+ }
287+}
288+
289+void tst_MediaPlaylist::addTwoTracksAndVerify()
290+{
291+ QMediaPlayer *player = new QMediaPlayer;
292+ QMediaPlaylist *playlist = new QMediaPlaylist;
293+ player->setPlaylist(playlist);
294+
295+ playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
296+ playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
297+
298+ QCOMPARE(playlist->mediaCount(), 2);
299+
300+ delete playlist;
301+ delete player;
302+}
303+
304+void tst_MediaPlaylist::insertTracksAtPositionAndVerify()
305+{
306+ QMediaPlayer *player = new QMediaPlayer;
307+ QMediaPlaylist *playlist = new QMediaPlaylist;
308+ player->setPlaylist(playlist);
309+
310+ QElapsedTimer timer;
311+ timer.start();
312+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
313+ waitTrackInserted(playlist);
314+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
315+ waitTrackInserted(playlist);
316+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
317+ waitTrackInserted(playlist);
318+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
319+ waitTrackInserted(playlist);
320+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
321+ waitTrackInserted(playlist);
322+ qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
323+
324+ QCOMPARE(playlist->mediaCount(), 5);
325+
326+ const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
327+ playlist->insertMedia(2, insertedTrack);
328+ waitTrackInserted(playlist);
329+
330+ qDebug() << "playlist->media(2):" << playlist->media(2).canonicalUrl();
331+ qDebug() << "insertedTrack:" << insertedTrack.canonicalUrl();
332+ QCOMPARE(playlist->media(2), insertedTrack);
333+
334+ delete playlist;
335+ delete player;
336+}
337+
338+void tst_MediaPlaylist::moveTrackAndVerify()
339+{
340+ QMediaPlayer *player = new QMediaPlayer;
341+ QMediaPlaylist *playlist = new QMediaPlaylist;
342+ player->setPlaylist(playlist);
343+
344+ QElapsedTimer timer;
345+ timer.start();
346+ QList<QMediaContent> content;
347+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
348+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
349+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
350+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
351+ const QMediaContent newLastTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
352+ content.push_back(newLastTrack);
353+ const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
354+ content.push_back(insertedTrack);
355+ playlist->addMedia(content);
356+ waitTrackInserted(playlist);
357+ qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
358+
359+ QCOMPARE(playlist->mediaCount(), 6);
360+
361+ connectSignal(playlist, Signals::MediaRemoved);
362+ connectSignal(playlist, Signals::MediaInserted);
363+ playlist->moveMedia(5, 2);
364+
365+ Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
366+ Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
367+ QCOMPARE(playlist->mediaCount(), 6);
368+
369+ delete playlist;
370+ delete player;
371+}
372+
373+void tst_MediaPlaylist::movePlayingTrackAndVerify()
374+{
375+ QMediaPlayer *player = new QMediaPlayer;
376+ QMediaPlaylist *playlist = new QMediaPlaylist;
377+ player->setPlaylist(playlist);
378+
379+ QElapsedTimer timer;
380+ timer.start();
381+ QList<QMediaContent> content;
382+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
383+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
384+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
385+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
386+ const QMediaContent newLastTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
387+ content.push_back(newLastTrack);
388+ const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/Ubuntu.ogg")));
389+ content.push_back(insertedTrack);
390+ playlist->addMedia(content);
391+ waitTrackInserted(playlist);
392+ qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
393+
394+ playlist->setCurrentIndex(5);
395+ waitCurrentIndexChange(playlist);
396+ QCOMPARE(playlist->currentIndex(), 5);
397+
398+ player->play();
399+
400+ QCOMPARE(playlist->mediaCount(), 6);
401+
402+ sleep(2);
403+
404+ connectSignal(playlist, Signals::MediaRemoved);
405+ connectSignal(playlist, Signals::MediaInserted);
406+ playlist->moveMedia(5, 2);
407+
408+ Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
409+ qDebug() << "Verifying the presence of MediaInserted signal in deque";
410+ Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
411+ QCOMPARE(playlist->mediaCount(), 6);
412+
413+ waitCurrentIndexChange(playlist);
414+
415+ QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
416+ QCOMPARE(playlist->currentIndex(), 2);
417+
418+ delete playlist;
419+ delete player;
420+}
421+
422+void tst_MediaPlaylist::addListOfTracksAndVerify()
423+{
424+ QMediaPlayer *player = new QMediaPlayer;
425+ QMediaPlaylist *playlist = new QMediaPlaylist;
426+ player->setPlaylist(playlist);
427+
428+ QList<QMediaContent> content;
429+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
430+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
431+
432+ playlist->addMedia(content);
433+
434+ QCOMPARE(playlist->mediaCount(), 2);
435+
436+ delete playlist;
437+ delete player;
438+}
439+
440+void tst_MediaPlaylist::addLargeListOfTracksAndVerify()
441+{
442+ QMediaPlayer *player = new QMediaPlayer;
443+ QMediaPlaylist *playlist = new QMediaPlaylist;
444+ player->setPlaylist(playlist);
445+
446+ // Total number of tracks added will be iterations * 5
447+ const uint16_t iterations = 20;
448+ QElapsedTimer timer;
449+ timer.start();
450+ for (uint16_t i=0; i<iterations; i++)
451+ {
452+ playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
453+ waitTrackInserted(playlist);
454+ playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
455+ waitTrackInserted(playlist);
456+ playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
457+ waitTrackInserted(playlist);
458+ playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
459+ waitTrackInserted(playlist);
460+ playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
461+ waitTrackInserted(playlist);
462+ }
463+ qDebug() << "** addMedia loop took" << timer.elapsed() << "milliseconds";
464+
465+ QCOMPARE(playlist->mediaCount(), iterations * 5);
466+
467+ delete playlist;
468+ delete player;
469+}
470+
471+void tst_MediaPlaylist::addLargeListOfTracksAtOnceAndVerify()
472+{
473+ QMediaPlayer *player = new QMediaPlayer;
474+ QMediaPlaylist *playlist = new QMediaPlaylist;
475+ player->setPlaylist(playlist);
476+
477+ QList<QMediaContent> content;
478+ int i;
479+ for (i=0; i<20; i++)
480+ {
481+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
482+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
483+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
484+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
485+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
486+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
487+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
488+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
489+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
490+ content.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
491+ }
492+
493+ QElapsedTimer timer;
494+ timer.start();
495+ playlist->addMedia(content);
496+ qDebug() << "** addMedia(QList) took" << timer.elapsed() << "milliseconds";
497+
498+ waitTrackInserted(playlist);
499+ QCOMPARE(playlist->mediaCount(), i * 10);
500+
501+ delete playlist;
502+ delete player;
503+}
504+
505+void tst_MediaPlaylist::addTwoListsOfTracksAtOnceAndVerify()
506+{
507+ QMediaPlayer *player = new QMediaPlayer;
508+ QMediaPlaylist *playlist = new QMediaPlaylist;
509+ player->setPlaylist(playlist);
510+
511+ QList<QMediaContent> content1;
512+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
513+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
514+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
515+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
516+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
517+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
518+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
519+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
520+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
521+ content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
522+
523+ QList<QMediaContent> content2;
524+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
525+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
526+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
527+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
528+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
529+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
530+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
531+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
532+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
533+ content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
534+
535+ QElapsedTimer timer;
536+ timer.start();
537+ playlist->addMedia(content1);
538+ qDebug() << "** First list addMedia(QList) took" << timer.elapsed() << "milliseconds";
539+
540+ waitTrackInserted(playlist);
541+ QCOMPARE(playlist->mediaCount(), 10);
542+
543+ timer.invalidate();
544+ timer.start();
545+ playlist->addMedia(content2);
546+ qDebug() << "** Second list addMedia(QList) took" << timer.elapsed() << "milliseconds";
547+
548+ waitTrackInserted(playlist);
549+ QCOMPARE(playlist->mediaCount(), 20);
550+
551+ delete playlist;
552+ delete player;
553+}
554+
555+void tst_MediaPlaylist::goToNextTrack()
556+{
557+ QMediaPlayer *player = new QMediaPlayer;
558+ QMediaPlaylist *playlist = new QMediaPlaylist;
559+ player->setPlaylist(playlist);
560+
561+ const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
562+ const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
563+ qDebug() << "audio URL: " << audio.toString();
564+ qDebug() << "video URL: " << video.toString();
565+ playlist->addMedia(audio);
566+ playlist->addMedia(video);
567+
568+ QCOMPARE(playlist->mediaCount(), 2);
569+
570+ player->play();
571+
572+ QCoreApplication::processEvents();
573+
574+ const QUrl audioToVerify(playlist->currentMedia().canonicalUrl());
575+ QCOMPARE(audioToVerify, audio);
576+
577+ playlist->next();
578+
579+ QCoreApplication::processEvents();
580+
581+ const QUrl videoToVerify(playlist->currentMedia().canonicalUrl());
582+ QCOMPARE(videoToVerify, video);
583+
584+ delete playlist;
585+ delete player;
586+}
587+
588+void tst_MediaPlaylist::goToPreviousTrack()
589+{
590+ QMediaPlayer *player = new QMediaPlayer;
591+ QMediaPlaylist *playlist = new QMediaPlaylist;
592+ player->setPlaylist(playlist);
593+
594+ const QUrl audio1(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
595+ const QUrl audio2(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
596+ playlist->addMedia(audio1);
597+ playlist->addMedia(audio2);
598+
599+ QCOMPARE(playlist->mediaCount(), 2);
600+ playlist->setCurrentIndex(1);
601+
602+ player->play();
603+
604+ QCoreApplication::processEvents();
605+
606+ const QUrl audio2ToVerify(playlist->currentMedia().canonicalUrl());
607+ QCOMPARE(audio2ToVerify, audio2);
608+
609+ playlist->previous();
610+
611+ QCoreApplication::processEvents();
612+
613+ const QUrl audio1ToVerify(playlist->currentMedia().canonicalUrl());
614+ QCOMPARE(audio2ToVerify, audio1);
615+ QCOMPARE(playlist->currentIndex(), 0);
616+
617+ delete playlist;
618+ delete player;
619+}
620+
621+void tst_MediaPlaylist::verifyMedia()
622+{
623+ QMediaPlayer *player = new QMediaPlayer;
624+ QMediaPlaylist *playlist = new QMediaPlaylist;
625+ player->setPlaylist(playlist);
626+
627+ const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
628+ const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
629+ qDebug() << "audio URL: " << audio.toString();
630+ qDebug() << "video URL: " << video.toString();
631+ playlist->addMedia(audio);
632+ playlist->addMedia(video);
633+
634+ QCOMPARE(playlist->mediaCount(), 2);
635+
636+ const QUrl audioToVerify(playlist->media(0).canonicalUrl());
637+ QCOMPARE(audioToVerify, audio);
638+
639+ const QUrl videoToVerify(playlist->media(1).canonicalUrl());
640+ QCOMPARE(videoToVerify, video);
641+
642+ delete playlist;
643+ delete player;
644+}
645+
646+void tst_MediaPlaylist::removeTrackAndVerify()
647+{
648+ QMediaPlayer *player = new QMediaPlayer;
649+ QMediaPlaylist *playlist = new QMediaPlaylist;
650+ player->setPlaylist(playlist);
651+
652+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
653+ const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
654+ playlist->addMedia(video);
655+
656+ waitTrackInserted(playlist);
657+ QCOMPARE(playlist->mediaCount(), 2);
658+
659+ playlist->removeMedia(0);
660+
661+ QCOMPARE(playlist->mediaCount(), 1);
662+
663+ const QUrl videoToVerify(playlist->media(0).canonicalUrl());
664+ QCOMPARE(videoToVerify, video);
665+
666+ delete playlist;
667+ delete player;
668+}
669+
670+void tst_MediaPlaylist::removeCurrentNonPlayingTrackAndVerify()
671+{
672+ QMediaPlayer *player = new QMediaPlayer;
673+ QMediaPlaylist *playlist = new QMediaPlaylist;
674+ player->setPlaylist(playlist);
675+
676+ QList<QMediaContent> content1;
677+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
678+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
679+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
680+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
681+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
682+ playlist->addMedia(content1);
683+ const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
684+ playlist->addMedia(track);
685+
686+ waitTrackInserted(playlist);
687+ QCOMPARE(playlist->mediaCount(), 6);
688+
689+ playlist->setCurrentIndex(2);
690+ // Wait for the currentMediaChanged signal to be emited
691+ waitTrackChange(playlist);
692+ // We should not be automatically playing
693+ QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
694+ QCOMPARE(playlist->currentIndex(), 2);
695+
696+ playlist->removeMedia(2);
697+
698+ // We should still not be playing
699+ QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
700+
701+ QCOMPARE(playlist->mediaCount(), 5);
702+
703+ const QUrl trackToVerify(playlist->media(4).canonicalUrl());
704+ QCOMPARE(trackToVerify, track);
705+
706+ delete playlist;
707+ delete player;
708+}
709+
710+void tst_MediaPlaylist::removeCurrentPlayingTrackAndVerify()
711+{
712+ QMediaPlayer *player = new QMediaPlayer;
713+ QMediaPlaylist *playlist = new QMediaPlaylist;
714+ player->setPlaylist(playlist);
715+
716+ QList<QMediaContent> content1;
717+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
718+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
719+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
720+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
721+ content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
722+ playlist->addMedia(content1);
723+ const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
724+ playlist->addMedia(track);
725+
726+ waitTrackInserted(playlist);
727+ QCOMPARE(playlist->mediaCount(), 6);
728+
729+ player->play();
730+
731+ playlist->setCurrentIndex(2);
732+ // Wait for the currentMediaChanged signal to be emited
733+ waitTrackChange(playlist);
734+ // We be playing
735+ QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
736+ QCOMPARE(playlist->currentIndex(), 2);
737+
738+ playlist->removeMedia(2);
739+
740+ // We should still be playing
741+ QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
742+
743+ QCOMPARE(playlist->mediaCount(), 5);
744+
745+ const QUrl trackToVerify(playlist->media(4).canonicalUrl());
746+ QCOMPARE(trackToVerify, track);
747+
748+ delete playlist;
749+ delete player;
750+}
751+
752+void tst_MediaPlaylist::removeLastCurrentPlayingTrackAndVerify()
753+{
754+ QMediaPlayer *player = new QMediaPlayer;
755+ QMediaPlaylist *playlist = new QMediaPlaylist;
756+ player->setPlaylist(playlist);
757+
758+ const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
759+ playlist->addMedia(track);
760+
761+ waitTrackInserted(playlist);
762+ QCOMPARE(playlist->mediaCount(), 1);
763+
764+ player->play();
765+
766+ playlist->setCurrentIndex(0);
767+ qDebug() << "Waiting for playback status to change to playing";
768+ // Wait for the currentMediaChanged signal to be emited
769+ waitTrackChange(playlist);
770+ // We be playing
771+ QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
772+
773+ qDebug() << "Removing track index 0";
774+ playlist->removeMedia(0);
775+
776+ waitTrackRemoved(playlist);
777+ // We should no longer be playing
778+ QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
779+
780+ QCOMPARE(playlist->mediaCount(), 0);
781+
782+ delete playlist;
783+ delete player;
784+}
785+
786+void tst_MediaPlaylist::verifyCurrentIndex()
787+{
788+ QMediaPlayer *player = new QMediaPlayer;
789+ QMediaPlaylist *playlist = new QMediaPlaylist;
790+ player->setPlaylist(playlist);
791+
792+ QList<QMediaContent> content;
793+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
794+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
795+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
796+ playlist->addMedia(content);
797+
798+ waitTrackInserted(playlist);
799+ QCOMPARE(playlist->mediaCount(), 3);
800+
801+ qDebug() << "Setting current index to be 1";
802+ playlist->setCurrentIndex(1);
803+
804+ // Wait for the currentMediaChanged signal to be emited
805+ waitTrackChange(playlist);
806+
807+ qDebug() << "Checking if current index is 1";
808+ QCOMPARE(playlist->currentIndex(), 1);
809+
810+ delete playlist;
811+ delete player;
812+}
813+
814+void tst_MediaPlaylist::verifyNextIndex()
815+{
816+ QMediaPlayer *player = new QMediaPlayer;
817+ QMediaPlaylist *playlist = new QMediaPlaylist;
818+ player->setPlaylist(playlist);
819+
820+ QList<QMediaContent> content;
821+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
822+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
823+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
824+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
825+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
826+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
827+ playlist->addMedia(content);
828+
829+ waitTrackInserted(playlist);
830+ QCOMPARE(playlist->mediaCount(), 6);
831+
832+ QCOMPARE(playlist->nextIndex(1), 1);
833+ QCOMPARE(playlist->nextIndex(4), 4);
834+ QCOMPARE(playlist->nextIndex(6), 0);
835+ QCOMPARE(playlist->nextIndex(7), 1);
836+ QCOMPARE(playlist->nextIndex(11), 5);
837+
838+ delete playlist;
839+ delete player;
840+}
841+
842+void tst_MediaPlaylist::verifyPreviousIndex()
843+{
844+ QMediaPlayer *player = new QMediaPlayer;
845+ QMediaPlaylist *playlist = new QMediaPlaylist;
846+ player->setPlaylist(playlist);
847+
848+ QList<QMediaContent> content;
849+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
850+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
851+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
852+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
853+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
854+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
855+ playlist->addMedia(content);
856+
857+ waitTrackInserted(playlist);
858+ QCOMPARE(playlist->mediaCount(), 6);
859+
860+ QCOMPARE(playlist->previousIndex(1), 5);
861+ QCOMPARE(playlist->previousIndex(4), 2);
862+ QCOMPARE(playlist->previousIndex(6), 0);
863+ QCOMPARE(playlist->previousIndex(11), 1);
864+ QCOMPARE(playlist->previousIndex(21), 3);
865+ QCOMPARE(playlist->previousIndex(19), 5);
866+
867+ delete playlist;
868+ delete player;
869+}
870+
871+void tst_MediaPlaylist::verifyPlaybackModeCurrentItemInLoop()
872+{
873+ QMediaPlayer *player = new QMediaPlayer;
874+ QMediaPlaylist *playlist = new QMediaPlaylist;
875+ player->setPlaylist(playlist);
876+
877+ connectSignal(playlist, Signals::MediaInserted);
878+
879+ QList<QMediaContent> content;
880+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
881+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
882+ playlist->addMedia(content);
883+
884+ // Wait until the first track is set as the current one
885+ waitTrackChange(playlist);
886+ Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
887+ QCOMPARE(playlist->mediaCount(), 2);
888+
889+ waitPlaybackModeChange(playlist, [playlist]()
890+ {
891+ playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
892+ });
893+
894+ player->play();
895+
896+ // Wait for the currentMediaChanged signal to be emited
897+ waitTrackChange(playlist);
898+
899+ QCOMPARE(playlist->currentIndex(), 0);
900+
901+ delete playlist;
902+ delete player;
903+}
904+
905+void tst_MediaPlaylist::verifyPlaybackModeSequential()
906+{
907+ QMediaPlayer *player = new QMediaPlayer;
908+ QMediaPlaylist *playlist = new QMediaPlaylist;
909+ player->setPlaylist(playlist);
910+
911+ connectSignal(playlist, Signals::MediaInserted);
912+
913+ QList<QMediaContent> content;
914+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
915+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
916+ playlist->addMedia(content);
917+
918+ // Wait until the first track is set as the current one
919+ waitTrackChange(playlist);
920+ Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
921+ QCOMPARE(playlist->mediaCount(), 2);
922+
923+ waitPlaybackModeChange(playlist, [playlist]()
924+ {
925+ playlist->setPlaybackMode(QMediaPlaylist::Sequential);
926+ });
927+
928+ player->play();
929+
930+ // Wait until the second track is selected
931+ waitTrackChange(playlist);
932+
933+ QCOMPARE(playlist->currentIndex(), 1);
934+
935+ delete playlist;
936+ delete player;
937+}
938+
939+void tst_MediaPlaylist::playReusePlayTrackList()
940+{
941+ QMediaPlayer *player = new QMediaPlayer;
942+ QMediaPlaylist *playlist = new QMediaPlaylist;
943+ player->setPlaylist(playlist);
944+
945+ const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
946+ const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
947+
948+ for (int i = 0; i < 5; ++i) {
949+ playlist->addMedia(audio);
950+ waitTrackInserted(playlist);
951+ playlist->addMedia(video);
952+ waitTrackInserted(playlist);
953+ playlist->addMedia(audio);
954+ waitTrackInserted(playlist);
955+ QCOMPARE(playlist->mediaCount(), 3);
956+
957+ player->play();
958+
959+ const QUrl audioToVerify(playlist->currentMedia().canonicalUrl());
960+ QCOMPARE(audioToVerify, audio);
961+
962+ player->stop();
963+
964+ connectSignal(playlist, Signals::MediaRemoved);
965+ playlist->clear();
966+
967+ Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
968+
969+ QCOMPARE(playlist->mediaCount(), 0);
970+ }
971+
972+ delete playlist;
973+ delete player;
974+}
975+
976+template<typename R>
977+void tst_MediaPlaylist::wait_for_signal(std::future<R> const& f)
978+{
979+ while (!is_ready<R>(f))
980+ {
981+ // Make sure we don't block the main QEventLoop, which
982+ // would hinder receiving the currentMediaChanged event above
983+ QCoreApplication::processEvents();
984+ std::this_thread::yield();
985+ }
986+}
987+
988+void tst_MediaPlaylist::waitTrackChange(QMediaPlaylist *playlist)
989+{
990+ QMediaContent current_media;
991+ std::promise<QMediaContent> promise;
992+ std::future<QMediaContent> future{promise.get_future()};
993+
994+ QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::currentMediaChanged,
995+ [&](const QMediaContent& content)
996+ {
997+ qDebug() << "currentMediaChanged to: " << content.canonicalUrl().toString();
998+ current_media = content;
999+ promise.set_value(current_media);
1000+ // Make sure the promise is not fulfilled twice
1001+ QObject::disconnect(c);
1002+ });
1003+
1004+ wait_for_signal(future);
1005+}
1006+
1007+void tst_MediaPlaylist::waitTrackInserted(QMediaPlaylist *playlist)
1008+{
1009+ int index = 0;
1010+ std::promise<int> promise;
1011+ std::future<int> future{promise.get_future()};
1012+
1013+ QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::mediaInserted,
1014+ [&](int start, int end)
1015+ {
1016+ qDebug() << "mediaInserted start: " << start << ", end: " << end;
1017+ index = end;
1018+ promise.set_value(index);
1019+ // Make sure the promise is not fulfilled twice
1020+ QObject::disconnect(c);
1021+ });
1022+
1023+ wait_for_signal(future);
1024+}
1025+
1026+void tst_MediaPlaylist::waitTrackRemoved(QMediaPlaylist *playlist)
1027+{
1028+ int index = 0;
1029+ std::promise<int> promise;
1030+ std::future<int> future{promise.get_future()};
1031+
1032+ QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::mediaRemoved,
1033+ [&](int start, int end)
1034+ {
1035+ qDebug() << "mediaRemoved start: " << start << ", end: " << end;
1036+ index = end;
1037+ promise.set_value(index);
1038+ // Make sure the promise is not fulfilled twice
1039+ QObject::disconnect(c);
1040+ });
1041+
1042+ wait_for_signal(future);
1043+}
1044+
1045+void tst_MediaPlaylist::waitPlaybackModeChange(QMediaPlaylist *playlist,
1046+ const std::function<void()>& action)
1047+{
1048+ QMediaPlaylist::PlaybackMode current_mode;
1049+ std::promise<QMediaPlaylist::PlaybackMode> promise;
1050+ std::future<QMediaPlaylist::PlaybackMode> future{promise.get_future()};
1051+
1052+ QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::playbackModeChanged,
1053+ [&](QMediaPlaylist::PlaybackMode mode)
1054+ {
1055+ qDebug() << "playbackModeChanged to: " << mode;
1056+ current_mode = mode;
1057+ promise.set_value(current_mode);
1058+ // Make sure the promise is not fulfilled twice
1059+ QObject::disconnect(c);
1060+ });
1061+
1062+ action();
1063+
1064+ wait_for_signal(future);
1065+}
1066+
1067+void tst_MediaPlaylist::waitCurrentIndexChange(QMediaPlaylist *playlist)
1068+{
1069+ int index = 0;
1070+ std::promise<int> promise;
1071+ std::future<int> future{promise.get_future()};
1072+
1073+ QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::currentIndexChanged,
1074+ [&](int i)
1075+ {
1076+ qDebug() << "currentIndexChanged index: " << i;
1077+ index = i;
1078+ promise.set_value(index);
1079+ // Make sure the promise is not fulfilled twice
1080+ QObject::disconnect(c);
1081+ });
1082+
1083+ wait_for_signal(future);
1084+}
1085+
1086+void tst_MediaPlaylist::connectSignal(QMediaPlaylist *playlist, Signals signal)
1087+{
1088+ switch (signal)
1089+ {
1090+ case Signals::Unknown:
1091+ break;
1092+ case Signals::CurrentMediaChanged:
1093+ {
1094+ connect(playlist, &QMediaPlaylist::currentMediaChanged, [&](const QMediaContent& content)
1095+ {
1096+ (void) content;
1097+ qDebug() << "Pushing CurrentMediaChanged onto m_signalsDeque";
1098+ m_signalsDeque.push_back(signal);
1099+ });
1100+ break;
1101+ }
1102+ case Signals::MediaInserted:
1103+ {
1104+ connect(playlist, &QMediaPlaylist::mediaInserted, [&](int start, int end)
1105+ {
1106+ (void) start;
1107+ (void) end;
1108+ qDebug() << "Pushing MediaInserted onto m_signalsDeque";
1109+ m_signalsDeque.push_back(signal);
1110+ });
1111+ break;
1112+ }
1113+ case Signals::MediaRemoved:
1114+ {
1115+ connect(playlist, &QMediaPlaylist::mediaRemoved, [&](int index)
1116+ {
1117+ (void) index;
1118+ qDebug() << "Pushing MediaRemoved onto m_signalsDeque";
1119+ m_signalsDeque.push_back(signal);
1120+ });
1121+ break;
1122+ }
1123+ default:
1124+ qWarning() << "Unknown signal type, can't add to queue:" << signal;
1125+ }
1126+}
1127+
1128+QTEST_GUILESS_MAIN(tst_MediaPlaylist)
1129
1130=== added file 'tests/integration/playlists/tst_mediaplaylist.h'
1131--- tests/integration/playlists/tst_mediaplaylist.h 1970-01-01 00:00:00 +0000
1132+++ tests/integration/playlists/tst_mediaplaylist.h 2016-02-22 16:57:32 +0000
1133@@ -0,0 +1,110 @@
1134+/*
1135+ * Copyright (C) 2015 Canonical, Ltd.
1136+ *
1137+ * This program is free software; you can redistribute it and/or modify
1138+ * it under the terms of the GNU Lesser General Public License as published by
1139+ * the Free Software Foundation; version 3.
1140+ *
1141+ * This program is distributed in the hope that it will be useful,
1142+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1143+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1144+ * GNU General Public License for more details.
1145+ *
1146+ * You should have received a copy of the GNU Lesser General Public License
1147+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1148+ */
1149+
1150+#ifndef TST_MEDIAPLAYLIST_H
1151+#define TST_MEDIAPLAYLIST_H
1152+
1153+#include <core/media/player.h>
1154+
1155+#include <deque>
1156+#include <future>
1157+#include <memory>
1158+
1159+#include <QMediaPlayer>
1160+#include <QMediaPlaylist>
1161+#include <QObject>
1162+
1163+class AalMediaPlaylistControl;
1164+class QMediaPlayer;
1165+
1166+class tst_MediaPlaylist : public QObject
1167+{
1168+ Q_OBJECT
1169+
1170+ AalMediaPlaylistControl *m_mediaPlaylistControl;
1171+
1172+public:
1173+ enum Signals {
1174+ Unknown,
1175+ CurrentMediaChanged,
1176+ MediaInserted,
1177+ MediaRemoved
1178+ };
1179+
1180+Q_SIGNALS:
1181+
1182+private Q_SLOTS:
1183+ // We want the setup to be run prior to every test case to
1184+ // ensure correct test isolation, see http://qt-project.org/doc/qt-5/qtest-overview.html.
1185+ void initTestCase();
1186+ void cleanupTestCase();
1187+
1188+ void init();
1189+
1190+ void constructDestroyRepeat();
1191+
1192+ void addTwoTracksAndVerify();
1193+ void insertTracksAtPositionAndVerify();
1194+ void moveTrackAndVerify();
1195+ void movePlayingTrackAndVerify();
1196+ void addListOfTracksAndVerify();
1197+ void addLargeListOfTracksAndVerify();
1198+ void addLargeListOfTracksAtOnceAndVerify();
1199+ void addTwoListsOfTracksAtOnceAndVerify();
1200+
1201+ void goToNextTrack();
1202+ void goToPreviousTrack();
1203+ void verifyMedia();
1204+
1205+ void removeTrackAndVerify();
1206+ void removeCurrentNonPlayingTrackAndVerify();
1207+ void removeCurrentPlayingTrackAndVerify();
1208+ void removeLastCurrentPlayingTrackAndVerify();
1209+
1210+ void verifyCurrentIndex();
1211+ void verifyNextIndex();
1212+ void verifyPreviousIndex();
1213+
1214+ void verifyPlaybackModeCurrentItemInLoop();
1215+ void verifyPlaybackModeSequential();
1216+
1217+ void playReusePlayTrackList();
1218+
1219+private:
1220+ std::deque<Signals> m_signalsDeque;
1221+
1222+ template<typename R>
1223+ bool is_ready(std::future<R> const& f)
1224+ { return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }
1225+
1226+ template<typename R>
1227+ void wait_for_signal(std::future<R> const& f);
1228+
1229+ void waitTrackChange(QMediaPlaylist *playlist);
1230+ void waitTrackInserted(QMediaPlaylist *playlist);
1231+ void waitTrackRemoved(QMediaPlaylist *playlist);
1232+ void waitPlaybackModeChange(QMediaPlaylist *playlist,
1233+ const std::function<void()>& action);
1234+ void waitCurrentIndexChange(QMediaPlaylist *playlist);
1235+
1236+ // A generic way of getting a signal registered into m_signalsDeque without blocking
1237+ // which can be used to later check the order of signals that were emitted. Simply call
1238+ // this method for each signal that you'd like to check and it'll be pushed onto the deque
1239+ // when it's fired.
1240+ void connectSignal(QMediaPlaylist *playlist, Signals signal);
1241+};
1242+
1243+#endif // TST_MEDIAPLAYLIST_H
1244
1245=== removed directory 'tests/integration/testdata'
1246=== removed file 'tests/integration/testdata/Ubuntu.ogg'
1247Binary 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
1248=== removed file 'tests/integration/testdata/testfile.mp4'
1249Binary 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
1250=== removed file 'tests/integration/testdata/testfile.ogg'
1251Binary 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
1252=== removed file 'tests/integration/testdata/testfile1.ogg'
1253Binary 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
1254=== removed file 'tests/integration/testdata/testfile2.ogg'
1255Binary 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
1256=== removed file 'tests/integration/testdata/testfile3.ogg'
1257Binary 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
1258=== removed file 'tests/integration/testdata/testfile4.ogg'
1259Binary 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
1260=== removed file 'tests/integration/tst_mediaplaylist.cpp'
1261--- tests/integration/tst_mediaplaylist.cpp 2015-11-17 22:25:36 +0000
1262+++ tests/integration/tst_mediaplaylist.cpp 1970-01-01 00:00:00 +0000
1263@@ -1,896 +0,0 @@
1264-/*
1265- * Copyright (C) 2015 Canonical, Ltd.
1266- *
1267- * This program is free software; you can redistribute it and/or modify
1268- * it under the terms of the GNU Lesser General Public License as published by
1269- * the Free Software Foundation; version 3.
1270- *
1271- * This program is distributed in the hope that it will be useful,
1272- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1273- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1274- * GNU General Public License for more details.
1275- *
1276- * You should have received a copy of the GNU Lesser General Public License
1277- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1278- */
1279-
1280-#include "tst_mediaplaylist.h"
1281-#include "aalutility.h"
1282-
1283-#include <thread>
1284-#include <unistd.h>
1285-
1286-#include <QMediaPlayer>
1287-#include <QMediaPlaylist>
1288-
1289-#include <QtTest/QtTest>
1290-
1291-void tst_MediaPlaylist::initTestCase()
1292-{
1293-}
1294-
1295-void tst_MediaPlaylist::cleanupTestCase()
1296-{
1297-}
1298-
1299-void tst_MediaPlaylist::init()
1300-{
1301- // NOTE: This sleep is currently needed in order to give media-hub a bit of time
1302- // between our different tests to cleanup and come back in a state where it can
1303- // respond to our requests.
1304- sleep(1);
1305-}
1306-
1307-void tst_MediaPlaylist::constructDestroyRepeat()
1308-{
1309- for (int i=0; i<25; i++)
1310- {
1311- QMediaPlayer *player = new QMediaPlayer;
1312- QMediaPlaylist *playlist = new QMediaPlaylist;
1313- player->setPlaylist(playlist);
1314-
1315- delete playlist;
1316- delete player;
1317- }
1318-}
1319-
1320-void tst_MediaPlaylist::addTwoTracksAndVerify()
1321-{
1322- QMediaPlayer *player = new QMediaPlayer;
1323- QMediaPlaylist *playlist = new QMediaPlaylist;
1324- player->setPlaylist(playlist);
1325-
1326- playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
1327- playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
1328-
1329- QCOMPARE(playlist->mediaCount(), 2);
1330-
1331- delete playlist;
1332- delete player;
1333-}
1334-
1335-void tst_MediaPlaylist::insertTracksAtPositionAndVerify()
1336-{
1337- QMediaPlayer *player = new QMediaPlayer;
1338- QMediaPlaylist *playlist = new QMediaPlaylist;
1339- player->setPlaylist(playlist);
1340-
1341- QElapsedTimer timer;
1342- timer.start();
1343- playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1344- waitTrackInserted(playlist);
1345- playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1346- waitTrackInserted(playlist);
1347- playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
1348- waitTrackInserted(playlist);
1349- playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
1350- waitTrackInserted(playlist);
1351- playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
1352- waitTrackInserted(playlist);
1353- qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
1354-
1355- QCOMPARE(playlist->mediaCount(), 5);
1356-
1357- const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
1358- playlist->insertMedia(2, insertedTrack);
1359- waitTrackInserted(playlist);
1360-
1361- qDebug() << "playlist->media(2):" << playlist->media(2).canonicalUrl();
1362- qDebug() << "insertedTrack:" << insertedTrack.canonicalUrl();
1363- QCOMPARE(playlist->media(2), insertedTrack);
1364-
1365- delete playlist;
1366- delete player;
1367-}
1368-
1369-void tst_MediaPlaylist::moveTrackAndVerify()
1370-{
1371- QMediaPlayer *player = new QMediaPlayer;
1372- QMediaPlaylist *playlist = new QMediaPlaylist;
1373- player->setPlaylist(playlist);
1374-
1375- QElapsedTimer timer;
1376- timer.start();
1377- QList<QMediaContent> content;
1378- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1379- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1380- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
1381- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
1382- const QMediaContent newLastTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
1383- content.push_back(newLastTrack);
1384- const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1385- content.push_back(insertedTrack);
1386- playlist->addMedia(content);
1387- waitTrackInserted(playlist);
1388- qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
1389-
1390- QCOMPARE(playlist->mediaCount(), 6);
1391-
1392- connectSignal(playlist, Signals::MediaRemoved);
1393- connectSignal(playlist, Signals::MediaInserted);
1394- playlist->moveMedia(5, 2);
1395-
1396- Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
1397- Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
1398- QCOMPARE(playlist->mediaCount(), 6);
1399-
1400- delete playlist;
1401- delete player;
1402-}
1403-
1404-void tst_MediaPlaylist::movePlayingTrackAndVerify()
1405-{
1406- QMediaPlayer *player = new QMediaPlayer;
1407- QMediaPlaylist *playlist = new QMediaPlaylist;
1408- player->setPlaylist(playlist);
1409-
1410- QElapsedTimer timer;
1411- timer.start();
1412- QList<QMediaContent> content;
1413- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1414- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1415- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
1416- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
1417- const QMediaContent newLastTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
1418- content.push_back(newLastTrack);
1419- const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/Ubuntu.ogg")));
1420- content.push_back(insertedTrack);
1421- playlist->addMedia(content);
1422- waitTrackInserted(playlist);
1423- qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
1424-
1425- playlist->setCurrentIndex(5);
1426- waitCurrentIndexChange(playlist);
1427- QCOMPARE(playlist->currentIndex(), 5);
1428-
1429- player->play();
1430-
1431- QCOMPARE(playlist->mediaCount(), 6);
1432-
1433- sleep(2);
1434-
1435- connectSignal(playlist, Signals::MediaRemoved);
1436- connectSignal(playlist, Signals::MediaInserted);
1437- playlist->moveMedia(5, 2);
1438-
1439- Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
1440- qDebug() << "Verifying the presence of MediaInserted signal in deque";
1441- Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
1442- QCOMPARE(playlist->mediaCount(), 6);
1443-
1444- waitCurrentIndexChange(playlist);
1445-
1446- QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
1447- QCOMPARE(playlist->currentIndex(), 2);
1448-
1449- delete playlist;
1450- delete player;
1451-}
1452-
1453-void tst_MediaPlaylist::addListOfTracksAndVerify()
1454-{
1455- QMediaPlayer *player = new QMediaPlayer;
1456- QMediaPlaylist *playlist = new QMediaPlaylist;
1457- player->setPlaylist(playlist);
1458-
1459- QList<QMediaContent> content;
1460- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
1461- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
1462-
1463- playlist->addMedia(content);
1464-
1465- QCOMPARE(playlist->mediaCount(), 2);
1466-
1467- delete playlist;
1468- delete player;
1469-}
1470-
1471-void tst_MediaPlaylist::addLargeListOfTracksAndVerify()
1472-{
1473- QMediaPlayer *player = new QMediaPlayer;
1474- QMediaPlaylist *playlist = new QMediaPlaylist;
1475- player->setPlaylist(playlist);
1476-
1477- // Total number of tracks added will be iterations * 5
1478- const uint16_t iterations = 20;
1479- QElapsedTimer timer;
1480- timer.start();
1481- for (uint16_t i=0; i<iterations; i++)
1482- {
1483- playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
1484- waitTrackInserted(playlist);
1485- playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
1486- waitTrackInserted(playlist);
1487- playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
1488- waitTrackInserted(playlist);
1489- playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
1490- waitTrackInserted(playlist);
1491- playlist->addMedia(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
1492- waitTrackInserted(playlist);
1493- }
1494- qDebug() << "** addMedia loop took" << timer.elapsed() << "milliseconds";
1495-
1496- QCOMPARE(playlist->mediaCount(), iterations * 5);
1497-
1498- delete playlist;
1499- delete player;
1500-}
1501-
1502-void tst_MediaPlaylist::addLargeListOfTracksAtOnceAndVerify()
1503-{
1504- QMediaPlayer *player = new QMediaPlayer;
1505- QMediaPlaylist *playlist = new QMediaPlaylist;
1506- player->setPlaylist(playlist);
1507-
1508- QList<QMediaContent> content;
1509- int i;
1510- for (i=0; i<20; i++)
1511- {
1512- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
1513- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
1514- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
1515- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
1516- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
1517- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
1518- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
1519- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
1520- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
1521- content.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
1522- }
1523-
1524- QElapsedTimer timer;
1525- timer.start();
1526- playlist->addMedia(content);
1527- qDebug() << "** addMedia(QList) took" << timer.elapsed() << "milliseconds";
1528-
1529- waitTrackInserted(playlist);
1530- QCOMPARE(playlist->mediaCount(), i * 10);
1531-
1532- delete playlist;
1533- delete player;
1534-}
1535-
1536-void tst_MediaPlaylist::addTwoListsOfTracksAtOnceAndVerify()
1537-{
1538- QMediaPlayer *player = new QMediaPlayer;
1539- QMediaPlaylist *playlist = new QMediaPlaylist;
1540- player->setPlaylist(playlist);
1541-
1542- QList<QMediaContent> content1;
1543- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
1544- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
1545- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
1546- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
1547- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
1548- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
1549- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
1550- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
1551- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
1552- content1.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
1553-
1554- QList<QMediaContent> content2;
1555- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
1556- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
1557- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
1558- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
1559- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile.mp4")));
1560- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile.ogg")));
1561- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile1.ogg")));
1562- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile2.ogg")));
1563- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile3.ogg")));
1564- content2.push_back(QUrl(QFINDTESTDATA("testdata/testfile4.ogg")));
1565-
1566- QElapsedTimer timer;
1567- timer.start();
1568- playlist->addMedia(content1);
1569- qDebug() << "** First list addMedia(QList) took" << timer.elapsed() << "milliseconds";
1570-
1571- waitTrackInserted(playlist);
1572- QCOMPARE(playlist->mediaCount(), 10);
1573-
1574- timer.invalidate();
1575- timer.start();
1576- playlist->addMedia(content2);
1577- qDebug() << "** Second list addMedia(QList) took" << timer.elapsed() << "milliseconds";
1578-
1579- waitTrackInserted(playlist);
1580- QCOMPARE(playlist->mediaCount(), 20);
1581-
1582- delete playlist;
1583- delete player;
1584-}
1585-
1586-void tst_MediaPlaylist::goToNextTrack()
1587-{
1588- QMediaPlayer *player = new QMediaPlayer;
1589- QMediaPlaylist *playlist = new QMediaPlaylist;
1590- player->setPlaylist(playlist);
1591-
1592- const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1593- const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1594- qDebug() << "audio URL: " << audio.toString();
1595- qDebug() << "video URL: " << video.toString();
1596- playlist->addMedia(audio);
1597- playlist->addMedia(video);
1598-
1599- QCOMPARE(playlist->mediaCount(), 2);
1600-
1601- player->play();
1602-
1603- QCoreApplication::processEvents();
1604-
1605- const QUrl audioToVerify(playlist->currentMedia().canonicalUrl());
1606- QCOMPARE(audioToVerify, audio);
1607-
1608- playlist->next();
1609-
1610- QCoreApplication::processEvents();
1611-
1612- const QUrl videoToVerify(playlist->currentMedia().canonicalUrl());
1613- QCOMPARE(videoToVerify, video);
1614-
1615- delete playlist;
1616- delete player;
1617-}
1618-
1619-void tst_MediaPlaylist::goToPreviousTrack()
1620-{
1621- QMediaPlayer *player = new QMediaPlayer;
1622- QMediaPlaylist *playlist = new QMediaPlaylist;
1623- player->setPlaylist(playlist);
1624-
1625- const QUrl audio1(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1626- const QUrl audio2(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1627- playlist->addMedia(audio1);
1628- playlist->addMedia(audio2);
1629-
1630- QCOMPARE(playlist->mediaCount(), 2);
1631- playlist->setCurrentIndex(1);
1632-
1633- player->play();
1634-
1635- QCoreApplication::processEvents();
1636-
1637- const QUrl audio2ToVerify(playlist->currentMedia().canonicalUrl());
1638- QCOMPARE(audio2ToVerify, audio2);
1639-
1640- playlist->previous();
1641-
1642- QCoreApplication::processEvents();
1643-
1644- const QUrl audio1ToVerify(playlist->currentMedia().canonicalUrl());
1645- QCOMPARE(audio2ToVerify, audio1);
1646- QCOMPARE(playlist->currentIndex(), 0);
1647-
1648- delete playlist;
1649- delete player;
1650-}
1651-
1652-void tst_MediaPlaylist::verifyMedia()
1653-{
1654- QMediaPlayer *player = new QMediaPlayer;
1655- QMediaPlaylist *playlist = new QMediaPlaylist;
1656- player->setPlaylist(playlist);
1657-
1658- const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1659- const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1660- qDebug() << "audio URL: " << audio.toString();
1661- qDebug() << "video URL: " << video.toString();
1662- playlist->addMedia(audio);
1663- playlist->addMedia(video);
1664-
1665- QCOMPARE(playlist->mediaCount(), 2);
1666-
1667- const QUrl audioToVerify(playlist->media(0).canonicalUrl());
1668- QCOMPARE(audioToVerify, audio);
1669-
1670- const QUrl videoToVerify(playlist->media(1).canonicalUrl());
1671- QCOMPARE(videoToVerify, video);
1672-
1673- delete playlist;
1674- delete player;
1675-}
1676-
1677-void tst_MediaPlaylist::removeTrackAndVerify()
1678-{
1679- QMediaPlayer *player = new QMediaPlayer;
1680- QMediaPlaylist *playlist = new QMediaPlaylist;
1681- player->setPlaylist(playlist);
1682-
1683- playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1684- const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1685- playlist->addMedia(video);
1686-
1687- waitTrackInserted(playlist);
1688- QCOMPARE(playlist->mediaCount(), 2);
1689-
1690- playlist->removeMedia(0);
1691-
1692- QCOMPARE(playlist->mediaCount(), 1);
1693-
1694- const QUrl videoToVerify(playlist->media(0).canonicalUrl());
1695- QCOMPARE(videoToVerify, video);
1696-
1697- delete playlist;
1698- delete player;
1699-}
1700-
1701-void tst_MediaPlaylist::removeCurrentNonPlayingTrackAndVerify()
1702-{
1703- QMediaPlayer *player = new QMediaPlayer;
1704- QMediaPlaylist *playlist = new QMediaPlaylist;
1705- player->setPlaylist(playlist);
1706-
1707- QList<QMediaContent> content1;
1708- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1709- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
1710- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
1711- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
1712- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
1713- playlist->addMedia(content1);
1714- const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1715- playlist->addMedia(track);
1716-
1717- waitTrackInserted(playlist);
1718- QCOMPARE(playlist->mediaCount(), 6);
1719-
1720- playlist->setCurrentIndex(2);
1721- // Wait for the currentMediaChanged signal to be emited
1722- waitTrackChange(playlist);
1723- // We should not be automatically playing
1724- QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
1725- QCOMPARE(playlist->currentIndex(), 2);
1726-
1727- playlist->removeMedia(2);
1728-
1729- // We should still not be playing
1730- QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
1731-
1732- QCOMPARE(playlist->mediaCount(), 5);
1733-
1734- const QUrl trackToVerify(playlist->media(4).canonicalUrl());
1735- QCOMPARE(trackToVerify, track);
1736-
1737- delete playlist;
1738- delete player;
1739-}
1740-
1741-void tst_MediaPlaylist::removeCurrentPlayingTrackAndVerify()
1742-{
1743- QMediaPlayer *player = new QMediaPlayer;
1744- QMediaPlaylist *playlist = new QMediaPlaylist;
1745- player->setPlaylist(playlist);
1746-
1747- QList<QMediaContent> content1;
1748- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1749- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
1750- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
1751- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
1752- content1.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
1753- playlist->addMedia(content1);
1754- const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1755- playlist->addMedia(track);
1756-
1757- waitTrackInserted(playlist);
1758- QCOMPARE(playlist->mediaCount(), 6);
1759-
1760- player->play();
1761-
1762- playlist->setCurrentIndex(2);
1763- // Wait for the currentMediaChanged signal to be emited
1764- waitTrackChange(playlist);
1765- // We be playing
1766- QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
1767- QCOMPARE(playlist->currentIndex(), 2);
1768-
1769- playlist->removeMedia(2);
1770-
1771- // We should still be playing
1772- QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
1773-
1774- QCOMPARE(playlist->mediaCount(), 5);
1775-
1776- const QUrl trackToVerify(playlist->media(4).canonicalUrl());
1777- QCOMPARE(trackToVerify, track);
1778-
1779- delete playlist;
1780- delete player;
1781-}
1782-
1783-void tst_MediaPlaylist::removeLastCurrentPlayingTrackAndVerify()
1784-{
1785- QMediaPlayer *player = new QMediaPlayer;
1786- QMediaPlaylist *playlist = new QMediaPlaylist;
1787- player->setPlaylist(playlist);
1788-
1789- const QUrl track(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1790- playlist->addMedia(track);
1791-
1792- waitTrackInserted(playlist);
1793- QCOMPARE(playlist->mediaCount(), 1);
1794-
1795- player->play();
1796-
1797- playlist->setCurrentIndex(0);
1798- qDebug() << "Waiting for playback status to change to playing";
1799- // Wait for the currentMediaChanged signal to be emited
1800- waitTrackChange(playlist);
1801- // We be playing
1802- QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
1803-
1804- qDebug() << "Removing track index 0";
1805- playlist->removeMedia(0);
1806-
1807- waitTrackRemoved(playlist);
1808- // We should no longer be playing
1809- QCOMPARE(player->state(), QMediaPlayer::State::StoppedState);
1810-
1811- QCOMPARE(playlist->mediaCount(), 0);
1812-
1813- delete playlist;
1814- delete player;
1815-}
1816-
1817-void tst_MediaPlaylist::verifyCurrentIndex()
1818-{
1819- QMediaPlayer *player = new QMediaPlayer;
1820- QMediaPlaylist *playlist = new QMediaPlaylist;
1821- player->setPlaylist(playlist);
1822-
1823- QList<QMediaContent> content;
1824- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1825- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1826- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1827- playlist->addMedia(content);
1828-
1829- waitTrackInserted(playlist);
1830- QCOMPARE(playlist->mediaCount(), 3);
1831-
1832- qDebug() << "Setting current index to be 1";
1833- playlist->setCurrentIndex(1);
1834-
1835- // Wait for the currentMediaChanged signal to be emited
1836- waitTrackChange(playlist);
1837-
1838- qDebug() << "Checking if current index is 1";
1839- QCOMPARE(playlist->currentIndex(), 1);
1840-
1841- delete playlist;
1842- delete player;
1843-}
1844-
1845-void tst_MediaPlaylist::verifyNextIndex()
1846-{
1847- QMediaPlayer *player = new QMediaPlayer;
1848- QMediaPlaylist *playlist = new QMediaPlaylist;
1849- player->setPlaylist(playlist);
1850-
1851- QList<QMediaContent> content;
1852- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1853- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1854- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1855- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1856- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1857- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1858- playlist->addMedia(content);
1859-
1860- waitTrackInserted(playlist);
1861- QCOMPARE(playlist->mediaCount(), 6);
1862-
1863- QCOMPARE(playlist->nextIndex(1), 1);
1864- QCOMPARE(playlist->nextIndex(4), 4);
1865- QCOMPARE(playlist->nextIndex(6), 0);
1866- QCOMPARE(playlist->nextIndex(7), 1);
1867- QCOMPARE(playlist->nextIndex(11), 5);
1868-
1869- delete playlist;
1870- delete player;
1871-}
1872-
1873-void tst_MediaPlaylist::verifyPreviousIndex()
1874-{
1875- QMediaPlayer *player = new QMediaPlayer;
1876- QMediaPlaylist *playlist = new QMediaPlaylist;
1877- player->setPlaylist(playlist);
1878-
1879- QList<QMediaContent> content;
1880- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1881- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1882- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1883- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1884- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1885- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1886- playlist->addMedia(content);
1887-
1888- waitTrackInserted(playlist);
1889- QCOMPARE(playlist->mediaCount(), 6);
1890-
1891- QCOMPARE(playlist->previousIndex(1), 5);
1892- QCOMPARE(playlist->previousIndex(4), 2);
1893- QCOMPARE(playlist->previousIndex(6), 0);
1894- QCOMPARE(playlist->previousIndex(11), 1);
1895- QCOMPARE(playlist->previousIndex(21), 3);
1896- QCOMPARE(playlist->previousIndex(19), 5);
1897-
1898- delete playlist;
1899- delete player;
1900-}
1901-
1902-void tst_MediaPlaylist::verifyPlaybackModeCurrentItemInLoop()
1903-{
1904- QMediaPlayer *player = new QMediaPlayer;
1905- QMediaPlaylist *playlist = new QMediaPlaylist;
1906- player->setPlaylist(playlist);
1907-
1908- connectSignal(playlist, Signals::MediaInserted);
1909-
1910- QList<QMediaContent> content;
1911- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1912- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1913- playlist->addMedia(content);
1914-
1915- // Wait until the first track is set as the current one
1916- waitTrackChange(playlist);
1917- Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
1918- QCOMPARE(playlist->mediaCount(), 2);
1919-
1920- waitPlaybackModeChange(playlist, [playlist]()
1921- {
1922- playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
1923- });
1924-
1925- player->play();
1926-
1927- // Wait for the currentMediaChanged signal to be emited
1928- waitTrackChange(playlist);
1929-
1930- QCOMPARE(playlist->currentIndex(), 0);
1931-
1932- delete playlist;
1933- delete player;
1934-}
1935-
1936-void tst_MediaPlaylist::verifyPlaybackModeSequential()
1937-{
1938- QMediaPlayer *player = new QMediaPlayer;
1939- QMediaPlaylist *playlist = new QMediaPlaylist;
1940- player->setPlaylist(playlist);
1941-
1942- connectSignal(playlist, Signals::MediaInserted);
1943-
1944- QList<QMediaContent> content;
1945- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1946- content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1947- playlist->addMedia(content);
1948-
1949- // Wait until the first track is set as the current one
1950- waitTrackChange(playlist);
1951- Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
1952- QCOMPARE(playlist->mediaCount(), 2);
1953-
1954- waitPlaybackModeChange(playlist, [playlist]()
1955- {
1956- playlist->setPlaybackMode(QMediaPlaylist::Sequential);
1957- });
1958-
1959- player->play();
1960-
1961- // Wait until the second track is selected
1962- waitTrackChange(playlist);
1963-
1964- QCOMPARE(playlist->currentIndex(), 1);
1965-
1966- delete playlist;
1967- delete player;
1968-}
1969-
1970-void tst_MediaPlaylist::playReusePlayTrackList()
1971-{
1972- QMediaPlayer *player = new QMediaPlayer;
1973- QMediaPlaylist *playlist = new QMediaPlaylist;
1974- player->setPlaylist(playlist);
1975-
1976- const QUrl audio(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
1977- const QUrl video(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
1978-
1979- for (int i = 0; i < 5; ++i) {
1980- playlist->addMedia(audio);
1981- waitTrackInserted(playlist);
1982- playlist->addMedia(video);
1983- waitTrackInserted(playlist);
1984- playlist->addMedia(audio);
1985- waitTrackInserted(playlist);
1986- QCOMPARE(playlist->mediaCount(), 3);
1987-
1988- player->play();
1989-
1990- const QUrl audioToVerify(playlist->currentMedia().canonicalUrl());
1991- QCOMPARE(audioToVerify, audio);
1992-
1993- player->stop();
1994-
1995- connectSignal(playlist, Signals::MediaRemoved);
1996- playlist->clear();
1997-
1998- Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaRemoved);
1999-
2000- QCOMPARE(playlist->mediaCount(), 0);
2001- }
2002-
2003- delete playlist;
2004- delete player;
2005-}
2006-
2007-template<typename R>
2008-void tst_MediaPlaylist::wait_for_signal(std::future<R> const& f)
2009-{
2010- while (!is_ready<R>(f))
2011- {
2012- // Make sure we don't block the main QEventLoop, which
2013- // would hinder receiving the currentMediaChanged event above
2014- QCoreApplication::processEvents();
2015- std::this_thread::yield();
2016- }
2017-}
2018-
2019-void tst_MediaPlaylist::waitTrackChange(QMediaPlaylist *playlist)
2020-{
2021- QMediaContent current_media;
2022- std::promise<QMediaContent> promise;
2023- std::future<QMediaContent> future{promise.get_future()};
2024-
2025- QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::currentMediaChanged,
2026- [&](const QMediaContent& content)
2027- {
2028- qDebug() << "currentMediaChanged to: " << content.canonicalUrl().toString();
2029- current_media = content;
2030- promise.set_value(current_media);
2031- // Make sure the promise is not fulfilled twice
2032- QObject::disconnect(c);
2033- });
2034-
2035- wait_for_signal(future);
2036-}
2037-
2038-void tst_MediaPlaylist::waitTrackInserted(QMediaPlaylist *playlist)
2039-{
2040- int index = 0;
2041- std::promise<int> promise;
2042- std::future<int> future{promise.get_future()};
2043-
2044- QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::mediaInserted,
2045- [&](int start, int end)
2046- {
2047- qDebug() << "mediaInserted start: " << start << ", end: " << end;
2048- index = end;
2049- promise.set_value(index);
2050- // Make sure the promise is not fulfilled twice
2051- QObject::disconnect(c);
2052- });
2053-
2054- wait_for_signal(future);
2055-}
2056-
2057-void tst_MediaPlaylist::waitTrackRemoved(QMediaPlaylist *playlist)
2058-{
2059- int index = 0;
2060- std::promise<int> promise;
2061- std::future<int> future{promise.get_future()};
2062-
2063- QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::mediaRemoved,
2064- [&](int start, int end)
2065- {
2066- qDebug() << "mediaRemoved start: " << start << ", end: " << end;
2067- index = end;
2068- promise.set_value(index);
2069- // Make sure the promise is not fulfilled twice
2070- QObject::disconnect(c);
2071- });
2072-
2073- wait_for_signal(future);
2074-}
2075-
2076-void tst_MediaPlaylist::waitPlaybackModeChange(QMediaPlaylist *playlist,
2077- const std::function<void()>& action)
2078-{
2079- QMediaPlaylist::PlaybackMode current_mode;
2080- std::promise<QMediaPlaylist::PlaybackMode> promise;
2081- std::future<QMediaPlaylist::PlaybackMode> future{promise.get_future()};
2082-
2083- QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::playbackModeChanged,
2084- [&](QMediaPlaylist::PlaybackMode mode)
2085- {
2086- qDebug() << "playbackModeChanged to: " << mode;
2087- current_mode = mode;
2088- promise.set_value(current_mode);
2089- // Make sure the promise is not fulfilled twice
2090- QObject::disconnect(c);
2091- });
2092-
2093- action();
2094-
2095- wait_for_signal(future);
2096-}
2097-
2098-void tst_MediaPlaylist::waitCurrentIndexChange(QMediaPlaylist *playlist)
2099-{
2100- int index = 0;
2101- std::promise<int> promise;
2102- std::future<int> future{promise.get_future()};
2103-
2104- QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::currentIndexChanged,
2105- [&](int i)
2106- {
2107- qDebug() << "currentIndexChanged index: " << i;
2108- index = i;
2109- promise.set_value(index);
2110- // Make sure the promise is not fulfilled twice
2111- QObject::disconnect(c);
2112- });
2113-
2114- wait_for_signal(future);
2115-}
2116-
2117-void tst_MediaPlaylist::connectSignal(QMediaPlaylist *playlist, Signals signal)
2118-{
2119- switch (signal)
2120- {
2121- case Signals::Unknown:
2122- break;
2123- case Signals::CurrentMediaChanged:
2124- {
2125- connect(playlist, &QMediaPlaylist::currentMediaChanged, [&](const QMediaContent& content)
2126- {
2127- (void) content;
2128- qDebug() << "Pushing CurrentMediaChanged onto m_signalsDeque";
2129- m_signalsDeque.push_back(signal);
2130- });
2131- break;
2132- }
2133- case Signals::MediaInserted:
2134- {
2135- connect(playlist, &QMediaPlaylist::mediaInserted, [&](int start, int end)
2136- {
2137- (void) start;
2138- (void) end;
2139- qDebug() << "Pushing MediaInserted onto m_signalsDeque";
2140- m_signalsDeque.push_back(signal);
2141- });
2142- break;
2143- }
2144- case Signals::MediaRemoved:
2145- {
2146- connect(playlist, &QMediaPlaylist::mediaRemoved, [&](int index)
2147- {
2148- (void) index;
2149- qDebug() << "Pushing MediaRemoved onto m_signalsDeque";
2150- m_signalsDeque.push_back(signal);
2151- });
2152- break;
2153- }
2154- default:
2155- qWarning() << "Unknown signal type, can't add to queue:" << signal;
2156- }
2157-}
2158-
2159-QTEST_GUILESS_MAIN(tst_MediaPlaylist)
2160
2161=== removed file 'tests/integration/tst_mediaplaylist.h'
2162--- tests/integration/tst_mediaplaylist.h 2015-11-17 22:25:36 +0000
2163+++ tests/integration/tst_mediaplaylist.h 1970-01-01 00:00:00 +0000
2164@@ -1,110 +0,0 @@
2165-/*
2166- * Copyright (C) 2015 Canonical, Ltd.
2167- *
2168- * This program is free software; you can redistribute it and/or modify
2169- * it under the terms of the GNU Lesser General Public License as published by
2170- * the Free Software Foundation; version 3.
2171- *
2172- * This program is distributed in the hope that it will be useful,
2173- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2174- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2175- * GNU General Public License for more details.
2176- *
2177- * You should have received a copy of the GNU Lesser General Public License
2178- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2179- */
2180-
2181-#ifndef TST_MEDIAPLAYLIST_H
2182-#define TST_MEDIAPLAYLIST_H
2183-
2184-#include <core/media/player.h>
2185-
2186-#include <deque>
2187-#include <future>
2188-#include <memory>
2189-
2190-#include <QMediaPlayer>
2191-#include <QMediaPlaylist>
2192-#include <QObject>
2193-
2194-class AalMediaPlaylistControl;
2195-class QMediaPlayer;
2196-
2197-class tst_MediaPlaylist : public QObject
2198-{
2199- Q_OBJECT
2200-
2201- AalMediaPlaylistControl *m_mediaPlaylistControl;
2202-
2203-public:
2204- enum Signals {
2205- Unknown,
2206- CurrentMediaChanged,
2207- MediaInserted,
2208- MediaRemoved
2209- };
2210-
2211-Q_SIGNALS:
2212-
2213-private Q_SLOTS:
2214- // We want the setup to be run prior to every test case to
2215- // ensure correct test isolation, see http://qt-project.org/doc/qt-5/qtest-overview.html.
2216- void initTestCase();
2217- void cleanupTestCase();
2218-
2219- void init();
2220-
2221- void constructDestroyRepeat();
2222-
2223- void addTwoTracksAndVerify();
2224- void insertTracksAtPositionAndVerify();
2225- void moveTrackAndVerify();
2226- void movePlayingTrackAndVerify();
2227- void addListOfTracksAndVerify();
2228- void addLargeListOfTracksAndVerify();
2229- void addLargeListOfTracksAtOnceAndVerify();
2230- void addTwoListsOfTracksAtOnceAndVerify();
2231-
2232- void goToNextTrack();
2233- void goToPreviousTrack();
2234- void verifyMedia();
2235-
2236- void removeTrackAndVerify();
2237- void removeCurrentNonPlayingTrackAndVerify();
2238- void removeCurrentPlayingTrackAndVerify();
2239- void removeLastCurrentPlayingTrackAndVerify();
2240-
2241- void verifyCurrentIndex();
2242- void verifyNextIndex();
2243- void verifyPreviousIndex();
2244-
2245- void verifyPlaybackModeCurrentItemInLoop();
2246- void verifyPlaybackModeSequential();
2247-
2248- void playReusePlayTrackList();
2249-
2250-private:
2251- std::deque<Signals> m_signalsDeque;
2252-
2253- template<typename R>
2254- bool is_ready(std::future<R> const& f)
2255- { return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }
2256-
2257- template<typename R>
2258- void wait_for_signal(std::future<R> const& f);
2259-
2260- void waitTrackChange(QMediaPlaylist *playlist);
2261- void waitTrackInserted(QMediaPlaylist *playlist);
2262- void waitTrackRemoved(QMediaPlaylist *playlist);
2263- void waitPlaybackModeChange(QMediaPlaylist *playlist,
2264- const std::function<void()>& action);
2265- void waitCurrentIndexChange(QMediaPlaylist *playlist);
2266-
2267- // A generic way of getting a signal registered into m_signalsDeque without blocking
2268- // which can be used to later check the order of signals that were emitted. Simply call
2269- // this method for each signal that you'd like to check and it'll be pushed onto the deque
2270- // when it's fired.
2271- void connectSignal(QMediaPlaylist *playlist, Signals signal);
2272-};
2273-
2274-#endif // TST_MEDIAPLAYLIST_H
2275
2276=== added directory 'tests/integration/uris'
2277=== added file 'tests/integration/uris/generate_test_files.sh'
2278--- tests/integration/uris/generate_test_files.sh 1970-01-01 00:00:00 +0000
2279+++ tests/integration/uris/generate_test_files.sh 2016-02-22 16:57:32 +0000
2280@@ -0,0 +1,25 @@
2281+#!/bin/bash
2282+
2283+WORKING_DIR=/tmp/qtubuntu-media
2284+BASE_FILE=$1/testdata/Ubuntu.ogg
2285+
2286+mkdir $WORKING_DIR
2287+
2288+echo "WORKING_DIR: $WORKING_DIR"
2289+echo "BASE_FILE: $BASE_FILE"
2290+
2291+# Creates several files with a single character filename that starts
2292+# at ASCII char #32 and ends with #126
2293+for i in {32..127} # from 'Space' to '~'
2294+do
2295+ # skip '"', '%', '<', '>', '.', 'DEL'
2296+ if [ $i -eq 127 ]
2297+ then
2298+ continue
2299+ else
2300+ chr=$(printf \\$(printf '%03o' $i))
2301+
2302+ echo "Creating file $chr.ogg from $BASE_FILE" > "$WORKING_DIR/log.txt"
2303+ cp $BASE_FILE "$WORKING_DIR/track$chr.ogg"
2304+ fi
2305+done
2306
2307=== added file 'tests/integration/uris/remove_test_files.sh'
2308--- tests/integration/uris/remove_test_files.sh 1970-01-01 00:00:00 +0000
2309+++ tests/integration/uris/remove_test_files.sh 2016-02-22 16:57:32 +0000
2310@@ -0,0 +1,7 @@
2311+#!/bin/bash
2312+
2313+WORKING_DIR=/tmp/qtubuntu-media
2314+
2315+if [ -d "$WORKING_DIR" ]; then
2316+ rm -r $WORKING_DIR
2317+fi
2318
2319=== added directory 'tests/integration/uris/testdata'
2320=== added file 'tests/integration/uris/testdata/Ubuntu.ogg'
2321Binary 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
2322=== added file 'tests/integration/uris/tst_mediauris.cpp'
2323--- tests/integration/uris/tst_mediauris.cpp 1970-01-01 00:00:00 +0000
2324+++ tests/integration/uris/tst_mediauris.cpp 2016-02-22 16:57:32 +0000
2325@@ -0,0 +1,116 @@
2326+/*
2327+ * Copyright (C) 2016 Canonical, Ltd.
2328+ *
2329+ * This program is free software; you can redistribute it and/or modify
2330+ * it under the terms of the GNU Lesser General Public License as published by
2331+ * the Free Software Foundation; version 3.
2332+ *
2333+ * This program is distributed in the hope that it will be useful,
2334+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2335+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2336+ * GNU General Public License for more details.
2337+ *
2338+ * You should have received a copy of the GNU Lesser General Public License
2339+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2340+ */
2341+
2342+#include "tst_mediauris.h"
2343+
2344+#include <unistd.h>
2345+
2346+#include <QMediaPlayer>
2347+#include <QMediaPlaylist>
2348+#include <QProcess>
2349+
2350+#include <QtTest/QtTest>
2351+
2352+void tst_MediaUris::initTestCase()
2353+{
2354+ QProcess p;
2355+ qDebug() << "Current working dir:" << QDir::currentPath();
2356+ p.start("../../../../tests/integration/uris/generate_test_files.sh",
2357+ QStringList() << QString{QDir::currentPath() + "/../../../../tests/integration/uris"});
2358+ p.waitForFinished();
2359+ QVERIFY(p.exitStatus() == QProcess::NormalExit);
2360+ QVERIFY(p.exitCode() == 0);
2361+}
2362+
2363+void tst_MediaUris::cleanupTestCase()
2364+{
2365+ QProcess p;
2366+ p.start("../../../../tests/integration/uris/remove_test_files.sh");
2367+ p.waitForFinished();
2368+ QVERIFY(p.exitStatus() == QProcess::NormalExit);
2369+ QVERIFY(p.exitCode() == 0);
2370+}
2371+
2372+void tst_MediaUris::init()
2373+{
2374+ // NOTE: This sleep is currently needed in order to give media-hub a bit of time
2375+ // between our different tests to cleanup and come back in a state where it can
2376+ // respond to our requests.
2377+ sleep(1);
2378+}
2379+
2380+void tst_MediaUris::verifySpecialAsciiCharsCanPlaySetMedia()
2381+{
2382+ QDir generatedFilesDir("/tmp/qtubuntu-media");
2383+ QStringList mediaFiles = generatedFilesDir.entryList(QDir::NoDotAndDotDot | QDir::System
2384+ | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
2385+
2386+ qDebug() << "mediaFiles.size():" << mediaFiles.size();
2387+
2388+ QMediaPlayer *player = new QMediaPlayer;
2389+
2390+ for (const QString &file : mediaFiles)
2391+ {
2392+ const QString fullFileUri {"file://" + generatedFilesDir.absolutePath() + "/" + file};
2393+ const QMediaContent content {QUrl{fullFileUri}};
2394+ qDebug() << "Trying to play file:" << fullFileUri;
2395+ player->setMedia(content);
2396+
2397+ player->play();
2398+ sleep(1);
2399+ qDebug() << "player->error():" << player->error();
2400+ qDebug() << "player->mediaStatus():" << player->mediaStatus();
2401+ QVERIFY(player->mediaStatus() != QMediaPlayer::InvalidMedia);
2402+ QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
2403+ player->stop();
2404+ }
2405+
2406+ delete player;
2407+}
2408+
2409+void tst_MediaUris::verifySpecialAsciiCharsCanPlayPlaylist()
2410+{
2411+ QDir generatedFilesDir("/tmp/qtubuntu-media");
2412+ QStringList mediaFiles = generatedFilesDir.entryList(QDir::NoDotAndDotDot | QDir::System
2413+ | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
2414+
2415+ qDebug() << "mediaFiles.size():" << mediaFiles.size();
2416+
2417+ QMediaPlayer *player = new QMediaPlayer;
2418+ QMediaPlaylist *playlist = new QMediaPlaylist;
2419+ player->setPlaylist(playlist);
2420+
2421+ for (const QString &file : mediaFiles)
2422+ {
2423+ QString fullFileUri {"file://" + generatedFilesDir.absolutePath() + "/" + file};
2424+ qDebug() << "Trying to play file:" << fullFileUri;
2425+ playlist->addMedia(QUrl(fullFileUri));
2426+
2427+ player->play();
2428+ sleep(1);
2429+ qDebug() << "player->error():" << player->error();
2430+ qDebug() << "player->mediaStatus():" << player->mediaStatus();
2431+ QVERIFY(player->mediaStatus() != QMediaPlayer::InvalidMedia);
2432+ QCOMPARE(player->state(), QMediaPlayer::State::PlayingState);
2433+ player->stop();
2434+ playlist->clear();
2435+ }
2436+
2437+ delete playlist;
2438+ delete player;
2439+}
2440+
2441+QTEST_GUILESS_MAIN(tst_MediaUris)
2442
2443=== added file 'tests/integration/uris/tst_mediauris.h'
2444--- tests/integration/uris/tst_mediauris.h 1970-01-01 00:00:00 +0000
2445+++ tests/integration/uris/tst_mediauris.h 2016-02-22 16:57:32 +0000
2446@@ -0,0 +1,51 @@
2447+/*
2448+ * Copyright (C) 2016 Canonical, Ltd.
2449+ *
2450+ * This program is free software; you can redistribute it and/or modify
2451+ * it under the terms of the GNU Lesser General Public License as published by
2452+ * the Free Software Foundation; version 3.
2453+ *
2454+ * This program is distributed in the hope that it will be useful,
2455+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2456+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2457+ * GNU General Public License for more details.
2458+ *
2459+ * You should have received a copy of the GNU Lesser General Public License
2460+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2461+ */
2462+
2463+#ifndef TST_MEDIAURIS_H
2464+#define TST_MEDIAURIS_H
2465+
2466+#include <core/media/player.h>
2467+
2468+#include <deque>
2469+#include <future>
2470+#include <memory>
2471+
2472+#include <QMediaPlayer>
2473+#include <QMediaPlaylist>
2474+#include <QObject>
2475+
2476+class AalMediaPlaylistControl;
2477+class QMediaPlayer;
2478+
2479+class tst_MediaUris : public QObject
2480+{
2481+ Q_OBJECT
2482+
2483+private Q_SLOTS:
2484+ // We want the setup to be run prior to every test case to
2485+ // ensure correct test isolation, see http://qt-project.org/doc/qt-5/qtest-overview.html.
2486+ void initTestCase();
2487+ void cleanupTestCase();
2488+
2489+ void init();
2490+
2491+ void verifySpecialAsciiCharsCanPlaySetMedia();
2492+ void verifySpecialAsciiCharsCanPlayPlaylist();
2493+
2494+private:
2495+};
2496+
2497+#endif // TST_MEDIAURIS_H
2498
2499=== added file 'tests/integration/uris/uris.pro'
2500--- tests/integration/uris/uris.pro 1970-01-01 00:00:00 +0000
2501+++ tests/integration/uris/uris.pro 2016-02-22 16:57:32 +0000
2502@@ -0,0 +1,23 @@
2503+include(../../coverage.pri)
2504+
2505+CONFIG += testcase
2506+QMAKE_CXXFLAGS += -std=c++11
2507+DEFINES += QT_NO_KEYWORDS
2508+TARGET = tst_uris
2509+
2510+QT += core multimedia testlib
2511+
2512+QT_TESTCASE_BUILDDIR = .
2513+
2514+INCLUDEPATH += ../../src/aal \
2515+ /usr/include/qt5/QtMultimedia \
2516+
2517+HEADERS += \
2518+ tst_mediauris.h
2519+
2520+SOURCES += \
2521+ tst_mediauris.cpp \
2522+ ../../../src/aal/aalutility.cpp
2523+
2524+# media-hub is required to be running for these tests
2525+#system(/sbin/stop media-hub; /sbin/start media-hub)

Subscribers

People subscribed via source and target branches

to all changes: