Merge lp:~phablet-team/qtubuntu-media/bg-playlist-fixes into lp:qtubuntu-media/stable

Proposed by Alfonso Sanchez-Beato
Status: Merged
Approved by: Jim Hodapp
Approved revision: 97
Merged at revision: 90
Proposed branch: lp:~phablet-team/qtubuntu-media/bg-playlist-fixes
Merge into: lp:qtubuntu-media/stable
Diff against target: 615 lines (+293/-33)
8 files modified
src/aal/aalmediaplayercontrol.cpp (+20/-11)
src/aal/aalmediaplayerservice.cpp (+5/-6)
src/aal/aalmediaplaylistcontrol.cpp (+19/-1)
src/aal/aalmediaplaylistcontrol.h (+2/-0)
src/aal/aalmediaplaylistprovider.cpp (+107/-13)
src/aal/aalmediaplaylistprovider.h (+9/-0)
tests/integration/tst_mediaplaylist.cpp (+126/-2)
tests/integration/tst_mediaplaylist.h (+5/-0)
To merge this branch: bzr merge lp:~phablet-team/qtubuntu-media/bg-playlist-fixes
Reviewer Review Type Date Requested Status
Jim Hodapp (community) code Approve
Review via email: mp+276164@code.launchpad.net

Commit message

Emit onPlaybackModeChanged (LP: #1510219).
Implements insertTrack() so that a client can move a track into a new position by first calling removeTrack().
Do proper clean-up when switching between playlist and playing a single
URI (LP: #1511029).

Description of the change

Emit onPlaybackModeChanged (LP: #1510219).
Implements insertTrack() so that a client can move a track into a new position by first calling removeTrack().
Do proper clean-up when switching between playlist and playing a single
URI (LP: #1511029).

To post a comment you must log in.
92. By Alfonso Sanchez-Beato

Do proper clean-up when switching between playlist and playing a single
URI (LP: #1511029)

Revision history for this message
Jim Hodapp (jhodapp) wrote :

Looks good for the parts that you contributed Alfonso. We won't top approve this until we get all of the qtubuntu-media fixes into this branch and better tested together.

review: Approve (code)
93. By Alfonso Sanchez-Beato

Fix double connections to events and avoid some unnecessay DBus calls.

94. By Alfonso Sanchez-Beato

Revert change that caused forward button not to work

95. By Alfonso Sanchez-Beato

Add support for TrackListReset signal, which is now emitted instead of
one TrackRemoved per track when we call media-hub's Reset DBus call.

96. By Alfonso Sanchez-Beato

Update current track index after performing operations that alter the
track list.

Revision history for this message
Jim Hodapp (jhodapp) wrote :

A few comments inline below.

review: Needs Fixing (code)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Will address comments asap. Please see also comment below.

97. By Alfonso Sanchez-Beato

Address review comments

Revision history for this message
Jim Hodapp (jhodapp) :
Revision history for this message
Jim Hodapp (jhodapp) wrote :

LGTM

review: Approve (code)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/aal/aalmediaplayercontrol.cpp'
2--- src/aal/aalmediaplayercontrol.cpp 2015-08-18 15:48:31 +0000
3+++ src/aal/aalmediaplayercontrol.cpp 2015-11-13 14:50:26 +0000
4@@ -198,20 +198,27 @@
5 qDebug() << __PRETTY_FUNCTION__ << endl;
6
7 qDebug() << "setMedia() media: " << AalUtility::unescape(media);
8+
9+ if (m_mediaContent == media) {
10+ qDebug() << "Same media as current";
11+ return;
12+ }
13+
14 m_mediaContent = media;
15
16- // Make sure we can actually load something valid
17+ QMediaPlayer::MediaStatus priorStatus = mediaStatus();
18+
19 if (!media.isNull())
20- {
21- QMediaPlayer::MediaStatus priorStatus = mediaStatus();
22 setMediaStatus(QMediaPlayer::LoadingMedia);
23- m_service->setMedia(AalUtility::unescape(media));
24- // This is important to do for QMediaPlaylist instances that
25- // are set to loop. Without this, such a playlist will only
26- // play once
27- if (priorStatus == QMediaPlayer::EndOfMedia)
28- stop();
29- }
30+
31+ // If there is no media this cleans up the play list
32+ m_service->setMedia(AalUtility::unescape(media));
33+
34+ // This is important to do for QMediaPlaylist instances that
35+ // are set to loop. Without this, such a playlist will only
36+ // play once
37+ if (priorStatus == QMediaPlayer::EndOfMedia)
38+ stop();
39
40 Q_EMIT mediaChanged(m_mediaContent);
41 }
42@@ -219,9 +226,11 @@
43 void AalMediaPlayerControl::play()
44 {
45 qDebug() << __PRETTY_FUNCTION__ << endl;
46+ m_service->play();
47
48+ // FIXME: Why are these setState needed? State is changed also when signals
49+ // from media-hub are received, which seems the right way to track it.
50 setState(QMediaPlayer::PlayingState);
51- m_service->play();
52 }
53
54 void AalMediaPlayerControl::pause()
55
56=== modified file 'src/aal/aalmediaplayerservice.cpp'
57--- src/aal/aalmediaplayerservice.cpp 2015-10-23 14:46:14 +0000
58+++ src/aal/aalmediaplayerservice.cpp 2015-11-13 14:50:26 +0000
59@@ -278,11 +278,6 @@
60 qWarning() << "Cannot open uri without a valid media-hub player session";
61 return;
62 }
63- if (url.isEmpty())
64- {
65- qWarning() << "Failed to set media source, url must be set." << endl;
66- return;
67- }
68
69 // This is critical to allowing a different video source to be able to play correctly
70 // if another video is already playing in the same AalMediaPlayerService instance
71@@ -293,8 +288,12 @@
72 }
73
74 qDebug() << "Setting media to: " << url;
75+
76+ if (m_mediaPlaylistProvider && url.isEmpty())
77+ m_mediaPlaylistProvider->clear();
78+
79 const media::Track::UriType uri(url.url().toStdString());
80- if (m_mediaPlaylistProvider == nullptr)
81+ if (m_mediaPlaylistProvider == nullptr || m_mediaPlaylistProvider->mediaCount() == 0)
82 {
83 try {
84 m_hubPlayerSession->open_uri(uri);
85
86=== modified file 'src/aal/aalmediaplaylistcontrol.cpp'
87--- src/aal/aalmediaplaylistcontrol.cpp 2015-08-11 15:45:59 +0000
88+++ src/aal/aalmediaplaylistcontrol.cpp 2015-11-13 14:50:26 +0000
89@@ -61,6 +61,7 @@
90 bool AalMediaPlaylistControl::setPlaylistProvider(QMediaPlaylistProvider *playlist)
91 {
92 m_playlistProvider = playlist;
93+ connect(playlist, SIGNAL(currentIndexChanged()), this, SLOT(onCurrentIndexChanged()));
94 Q_EMIT playlistProviderChanged();
95 return true;
96 }
97@@ -120,8 +121,8 @@
98 //const int reducedSteps = steps - ((steps / tracklistSize) * tracklistSize);
99 // Calculate how many of x are in tracklistSize to reduce the calculation
100 // to only wrap around the list one time
101+#ifdef VERBOSE_DEBUG
102 const uint16_t m = (uint16_t)std::abs(x) / (uint16_t)tracklistSize; // 3
103-#ifdef VERBOSE_DEBUG
104 qDebug() << "m_currentIndex: " << m_currentIndex;
105 qDebug() << "steps: " << steps;
106 qDebug() << "tracklistSize: " << tracklistSize;
107@@ -237,6 +238,8 @@
108 qWarning() << "Unknown playback mode: " << mode;
109 m_hubPlayerSession->shuffle() = false;
110 }
111+
112+ Q_EMIT playbackModeChanged(mode);
113 }
114
115 void AalMediaPlaylistControl::setPlayerSession(const std::shared_ptr<core::ubuntu::media::Player>& playerSession)
116@@ -259,6 +262,7 @@
117 if (!id.empty())
118 {
119 m_currentIndex = aalMediaPlaylistProvider()->indexOfTrack(id);
120+ m_currentId = id;
121 qDebug() << "m_currentIndex updated to: " << m_currentIndex;
122 const QMediaContent content = playlistProvider()->media(m_currentIndex);
123 Q_EMIT currentMediaChanged(content);
124@@ -266,8 +270,22 @@
125 }
126 }
127
128+void AalMediaPlaylistControl::onCurrentIndexChanged()
129+{
130+ int index = aalMediaPlaylistProvider()->indexOfTrack(m_currentId);
131+
132+ if (index != m_currentIndex) {
133+ qDebug() << "Index changed to " << index;
134+ m_currentIndex = index;
135+ Q_EMIT currentIndexChanged(m_currentIndex);
136+ }
137+}
138+
139 void AalMediaPlaylistControl::connect_signals()
140 {
141+ // Avoid duplicated subscriptions
142+ disconnect_signals();
143+
144 if (!m_hubTrackList) {
145 qWarning() << "Can't connect to track list signals as it doesn't exist";
146 return;
147
148=== modified file 'src/aal/aalmediaplaylistcontrol.h'
149--- src/aal/aalmediaplaylistcontrol.h 2015-07-24 18:29:42 +0000
150+++ src/aal/aalmediaplaylistcontrol.h 2015-11-13 14:50:26 +0000
151@@ -62,6 +62,7 @@
152
153 private Q_SLOTS:
154 void onTrackChanged(const core::ubuntu::media::Track::Id& id);
155+ void onCurrentIndexChanged();
156
157 private:
158 void connect_signals();
159@@ -73,6 +74,7 @@
160 QMediaPlaylistProvider *m_playlistProvider;
161
162 int m_currentIndex;
163+ core::ubuntu::media::Track::Id m_currentId;
164
165 core::Connection m_trackChangedConnection;
166 };
167
168=== modified file 'src/aal/aalmediaplaylistprovider.cpp'
169--- src/aal/aalmediaplaylistprovider.cpp 2015-10-23 15:08:10 +0000
170+++ src/aal/aalmediaplaylistprovider.cpp 2015-11-13 14:50:26 +0000
171@@ -36,7 +36,9 @@
172 : QMediaPlaylistProvider(parent),
173 m_trackAddedConnection(the_void.connect([](){})),
174 m_tracksAddedConnection(the_void.connect([](){})),
175- m_trackRemovedConnection(the_void.connect([](){}))
176+ m_trackRemovedConnection(the_void.connect([](){})),
177+ m_trackListResetConnection(the_void.connect([](){})),
178+ m_insertTrackIndex(-1)
179 {
180 qDebug() << Q_FUNC_INFO;
181 qRegisterMetaType<core::ubuntu::media::Track::Id>();
182@@ -50,7 +52,6 @@
183
184 int AalMediaPlaylistProvider::mediaCount() const
185 {
186- qDebug() << Q_FUNC_INFO;
187 if (!m_hubTrackList) {
188 qWarning() << "Tracklist doesn't exist";
189 return 0;
190@@ -99,6 +100,8 @@
191
192 bool AalMediaPlaylistProvider::addMedia(const QMediaContent &content)
193 {
194+ qDebug() << Q_FUNC_INFO;
195+
196 if (!m_hubTrackList) {
197 qWarning() << "Track list does not exist so can't add a new track";
198 return false;
199@@ -115,6 +118,7 @@
200 const int newIndex = track_index_lut.size();
201 Q_EMIT mediaAboutToBeInserted(newIndex, newIndex);
202 try {
203+ qDebug() << "Adding track " << urlStr.c_str();
204 m_hubTrackList->add_track_with_uri_at(urlStr, after_empty_track, make_current);
205 }
206 catch (const media::TrackList::Errors::InsufficientPermissionsToAddTrack &e)
207@@ -132,6 +136,8 @@
208
209 bool AalMediaPlaylistProvider::addMedia(const QList<QMediaContent> &contentList)
210 {
211+ qDebug() << Q_FUNC_INFO << " num " << contentList.size();
212+
213 if (contentList.empty())
214 return false;
215
216@@ -141,8 +147,10 @@
217 }
218
219 media::TrackList::ContainerURI uris;
220- for (const auto mediaContent : contentList)
221+ for (const auto mediaContent : contentList) {
222+ qDebug() << "Adding track " << AalUtility::unescape(mediaContent).toString();
223 uris.push_back(AalUtility::unescape_str(mediaContent));
224+ }
225
226 const media::Track::Id after_empty_track = media::TrackList::after_empty_track();
227 const int newIndex = track_index_lut.size();
228@@ -165,12 +173,52 @@
229
230 bool AalMediaPlaylistProvider::insertMedia(int index, const QMediaContent &content)
231 {
232- (void) index;
233- (void) content;
234-
235- qWarning() << Q_FUNC_INFO << " - Not yet implemented";
236-
237- return false;
238+ if (!m_hubTrackList) {
239+ qWarning() << "Track list does not exist so can't add a new track";
240+ return false;
241+ }
242+
243+ if (index < 0 or index >= static_cast<int>(track_index_lut.size())) {
244+ qWarning() << Q_FUNC_INFO << "index is out of valid range";
245+ return false;
246+ }
247+
248+ const QUrl url = content.canonicalUrl();
249+ std::string urlStr = AalUtility::unescape_str(content);
250+ if (url.scheme().isEmpty() and url.scheme() != "file")
251+ urlStr = "file://" + urlStr;
252+
253+ const media::Track::Id after_this_track = trackOfIndex(index);
254+ if (after_this_track.empty()) {
255+ qWarning() << Q_FUNC_INFO
256+ << "failed to insertMedia due to failure to look up correct insertion position";
257+ return false;
258+ }
259+
260+ qDebug() << "after_this_track:" << after_this_track.c_str();
261+
262+ static const bool make_current = false;
263+ const int newIndex = index + 1;
264+ if (newIndex >= static_cast<int>(track_index_lut.size())) {
265+ qWarning() << Q_FUNC_INFO << "newIndex is greater than track_index_lut.size()";
266+ return false;
267+ }
268+ Q_EMIT mediaAboutToBeInserted(newIndex, newIndex);
269+ m_insertTrackIndex = newIndex;
270+ try {
271+ m_hubTrackList->add_track_with_uri_at(urlStr, after_this_track, make_current);
272+ }
273+ catch (const media::TrackList::Errors::InsufficientPermissionsToAddTrack &e)
274+ {
275+ qWarning() << "Failed to add track '" << content.canonicalUrl().toString() << "' to playlist: " << e.what();
276+ return false;
277+ }
278+ catch (const std::runtime_error &e) {
279+ qWarning() << "Failed to add track '" << content.canonicalUrl().toString() << "' to playlist: " << e.what();
280+ return false;
281+ }
282+
283+ return true;
284 }
285
286 bool AalMediaPlaylistProvider::insertMedia(int index, const QList<QMediaContent> &content)
287@@ -228,6 +276,19 @@
288
289 try {
290 m_hubTrackList->reset();
291+
292+ // We do not wait for the TrackListReset signal to empty the lut to
293+ // avoid sync problems.
294+ // TODO: Do the same in other calls if possible, as these calls are
295+ // considered to be synchronous, and the job can be considered finished
296+ // when the DBus call returns without error. If we need some information
297+ // from the signal we should block until it arrives.
298+ int num_tracks = track_index_lut.size();
299+ if (num_tracks > 0) {
300+ Q_EMIT mediaAboutToBeRemoved(0, num_tracks - 1);
301+ track_index_lut.clear();
302+ Q_EMIT mediaRemoved(0, num_tracks - 1);
303+ }
304 }
305 catch (const std::runtime_error &e) {
306 qWarning() << "Failed to clear the playlist: " << e.what();
307@@ -248,6 +309,8 @@
308 qWarning() << "FATAL: Failed to retrieve the current player session TrackList: " << e.what();
309 }
310
311+ /* Disconnect first to avoid duplicated calls */
312+ disconnect_signals();
313 connect_signals();
314 }
315
316@@ -258,21 +321,42 @@
317 return;
318 }
319
320+ qDebug() << Q_FUNC_INFO;
321+
322 m_trackAddedConnection = m_hubTrackList->on_track_added().connect([this](const media::Track::Id& id)
323 {
324- track_index_lut.push_back(id);
325+ // If m_insertTrackIndex >= 0, then the user requested to insert a track and we don't want to push
326+ // this track onto the back of the track_index_lut.
327+ // Otherwise the user requested to add a track which automatically gets pushed onto the back.
328+ if (m_insertTrackIndex >= 0)
329+ {
330+ const media::Track::Id after_track_id = trackOfIndex(m_insertTrackIndex);
331+ qDebug() << "Inserting track into specific position after track id:" << after_track_id.c_str();
332+ const auto trackPos = std::find(track_index_lut.begin(), track_index_lut.end(), after_track_id);
333+ if (trackPos != track_index_lut.end())
334+ track_index_lut.insert(trackPos - 1, id);
335+ else
336+ qWarning() << "Failed to find insertion point for non-existent track id: " << after_track_id.c_str();
337+
338+ // No longer doing an insert track, so reset flag
339+ m_insertTrackIndex = -1;
340+ }
341+ else
342+ {
343+ track_index_lut.push_back(id);
344+ qDebug() << "Added track id:" << id.c_str();
345+ }
346+
347 // This must come after push_back(id) or indexOfTrack won't find id in the LUT
348 const int index = indexOfTrack(id);
349 Q_EMIT mediaAboutToBeInserted(index, index);
350 qDebug() << "mediaInserted, index: " << index;
351 Q_EMIT mediaInserted(index, index);
352+ Q_EMIT currentIndexChanged();
353 });
354
355 m_tracksAddedConnection = m_hubTrackList->on_tracks_added().connect([this](const media::TrackList::ContainerURI& tracks)
356 {
357- // TODO: Fill in on_tracks_added here
358- qDebug() << "on_tracks_added(), tracks.size()" << tracks.size();
359-
360 int i =0;
361 for (const media::Track::Id& id : tracks)
362 {
363@@ -292,6 +376,7 @@
364 Q_EMIT mediaAboutToBeInserted(first_index, last_index);
365 qDebug() << "mediaInserted, first_index: " << first_index << " last_index: " << last_index;
366 Q_EMIT mediaInserted(first_index, last_index);
367+ Q_EMIT currentIndexChanged();
368 });
369
370 m_trackRemovedConnection = m_hubTrackList->on_track_removed().connect([this](const media::Track::Id& id)
371@@ -305,6 +390,12 @@
372
373 // Removed one track, so start and end are the same index values
374 Q_EMIT mediaRemoved(index, index);
375+ Q_EMIT currentIndexChanged();
376+ });
377+
378+ m_trackListResetConnection = m_hubTrackList->on_track_list_reset().connect([this]()
379+ {
380+ qDebug() << "TrackListReset signal received";
381 });
382 }
383
384@@ -312,6 +403,9 @@
385 {
386 qDebug() << Q_FUNC_INFO;
387
388+ if (m_trackListResetConnection.is_connected())
389+ m_trackListResetConnection.disconnect();
390+
391 if (m_trackRemovedConnection.is_connected())
392 m_trackRemovedConnection.disconnect();
393
394
395=== modified file 'src/aal/aalmediaplaylistprovider.h'
396--- src/aal/aalmediaplaylistprovider.h 2015-10-21 19:42:13 +0000
397+++ src/aal/aalmediaplaylistprovider.h 2015-11-13 14:50:26 +0000
398@@ -25,6 +25,7 @@
399
400 #include <core/connection.h>
401
402+#include <atomic>
403 #include <memory>
404 #include <vector>
405
406@@ -54,6 +55,9 @@
407 bool removeMedia(int start, int end);
408 bool clear();
409
410+Q_SIGNALS:
411+ void currentIndexChanged();
412+
413 private:
414 void setPlayerSession(const std::shared_ptr<core::ubuntu::media::Player>& playerSession);
415 void connect_signals();
416@@ -69,11 +73,16 @@
417 core::Connection m_trackAddedConnection;
418 core::Connection m_tracksAddedConnection;
419 core::Connection m_trackRemovedConnection;
420+ core::Connection m_trackListResetConnection;
421
422 // Simple table that holds a list (order is significant and explicit) of
423 // Track::Id's for a lookup. track_index_lut.at[x] gives the corresponding
424 // Track::Id for index x, and vice-versa.
425 std::vector<core::ubuntu::media::Track::Id> track_index_lut;
426+
427+ // Did the client perform an insertTrack() (as opposed to an addTrack()) operation?
428+ // If yes, the index will be zero or greater, if not index will be -1;
429+ std::atomic<int> m_insertTrackIndex;
430 };
431
432 QT_END_NAMESPACE
433
434=== modified file 'tests/integration/tst_mediaplaylist.cpp'
435--- tests/integration/tst_mediaplaylist.cpp 2015-10-22 17:27:54 +0000
436+++ tests/integration/tst_mediaplaylist.cpp 2015-11-13 14:50:26 +0000
437@@ -69,6 +69,83 @@
438 delete player;
439 }
440
441+void tst_MediaPlaylist::insertTracksAtPositionAndVerify()
442+{
443+ QMediaPlayer *player = new QMediaPlayer;
444+ QMediaPlaylist *playlist = new QMediaPlaylist;
445+ player->setPlaylist(playlist);
446+
447+ QElapsedTimer timer;
448+ timer.start();
449+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
450+ waitTrackInserted(playlist);
451+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
452+ waitTrackInserted(playlist);
453+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
454+ waitTrackInserted(playlist);
455+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
456+ waitTrackInserted(playlist);
457+ playlist->addMedia(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
458+ waitTrackInserted(playlist);
459+ qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
460+
461+ QCOMPARE(playlist->mediaCount(), 5);
462+
463+ const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile4.ogg")));
464+ playlist->insertMedia(2, insertedTrack);
465+ waitTrackInserted(playlist);
466+
467+ qDebug() << "playlist->media(2):" << playlist->media(2).canonicalUrl();
468+ qDebug() << "insertedTrack:" << insertedTrack.canonicalUrl();
469+ QCOMPARE(playlist->media(2), insertedTrack);
470+
471+ delete playlist;
472+ delete player;
473+}
474+
475+void tst_MediaPlaylist::moveTrackAndVerify()
476+{
477+ QMediaPlayer *player = new QMediaPlayer;
478+ QMediaPlaylist *playlist = new QMediaPlaylist;
479+ player->setPlaylist(playlist);
480+
481+ QElapsedTimer timer;
482+ timer.start();
483+ QList<QMediaContent> content;
484+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
485+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.ogg")));
486+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile1.ogg")));
487+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile2.ogg")));
488+ const QMediaContent newLastTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile3.ogg")));
489+ content.push_back(newLastTrack);
490+ content.push_back(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
491+ playlist->addMedia(content);
492+ waitTrackInserted(playlist);
493+ qDebug() << "** addMedia took" << timer.elapsed() << "milliseconds";
494+
495+ QCOMPARE(playlist->mediaCount(), 6);
496+
497+ // Remove our track of interest
498+ playlist->removeMedia(5);
499+ waitTrackRemoved(playlist);
500+ QCOMPARE(playlist->mediaCount(), 5);
501+
502+ // "Move" it by inserting it where we want it
503+ const QMediaContent insertedTrack(QUrl("file://" + QFINDTESTDATA("testdata/testfile.mp4")));
504+ playlist->insertMedia(2, insertedTrack);
505+ waitTrackInserted(playlist);
506+
507+ qDebug() << "playlist->media(2):" << playlist->media(2).canonicalUrl();
508+ qDebug() << "insertedTrack:" << insertedTrack.canonicalUrl();
509+ QCOMPARE(playlist->media(2), insertedTrack);
510+ QCOMPARE(playlist->mediaCount(), 6);
511+
512+ QCOMPARE(playlist->media(5), newLastTrack);
513+
514+ delete playlist;
515+ delete player;
516+}
517+
518 void tst_MediaPlaylist::addListOfTracksAndVerify()
519 {
520 QMediaPlayer *player = new QMediaPlayer;
521@@ -420,7 +497,10 @@
522 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
523 QCOMPARE(playlist->mediaCount(), 2);
524
525- playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
526+ waitPlaybackModeChange(playlist, [playlist]()
527+ {
528+ playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
529+ });
530
531 player->play();
532
533@@ -451,7 +531,10 @@
534 Q_ASSERT(m_signalsDeque.pop_front() == Signals::MediaInserted);
535 QCOMPARE(playlist->mediaCount(), 2);
536
537- playlist->setPlaybackMode(QMediaPlaylist::Sequential);
538+ waitPlaybackModeChange(playlist, [playlist]()
539+ {
540+ playlist->setPlaybackMode(QMediaPlaylist::Sequential);
541+ });
542
543 player->play();
544
545@@ -550,6 +633,47 @@
546 wait_for_signal(future);
547 }
548
549+void tst_MediaPlaylist::waitTrackRemoved(QMediaPlaylist *playlist)
550+{
551+ int index = 0;
552+ std::promise<int> promise;
553+ std::future<int> future{promise.get_future()};
554+
555+ QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::mediaRemoved,
556+ [&](int start, int end)
557+ {
558+ qDebug() << "mediaRemoved start: " << start << ", end: " << end;
559+ index = end;
560+ promise.set_value(index);
561+ // Make sure the promise is not fulfilled twice
562+ QObject::disconnect(c);
563+ });
564+
565+ wait_for_signal(future);
566+}
567+
568+void tst_MediaPlaylist::waitPlaybackModeChange(QMediaPlaylist *playlist,
569+ const std::function<void()>& action)
570+{
571+ QMediaPlaylist::PlaybackMode current_mode;
572+ std::promise<QMediaPlaylist::PlaybackMode> promise;
573+ std::future<QMediaPlaylist::PlaybackMode> future{promise.get_future()};
574+
575+ QMetaObject::Connection c = connect(playlist, &QMediaPlaylist::playbackModeChanged,
576+ [&](QMediaPlaylist::PlaybackMode mode)
577+ {
578+ qDebug() << "playbackModeChanged to: " << mode;
579+ current_mode = mode;
580+ promise.set_value(current_mode);
581+ // Make sure the promise is not fulfilled twice
582+ QObject::disconnect(c);
583+ });
584+
585+ action();
586+
587+ wait_for_signal(future);
588+}
589+
590 void tst_MediaPlaylist::connectSignal(QMediaPlaylist *playlist, Signals signal)
591 {
592 switch (signal)
593
594=== modified file 'tests/integration/tst_mediaplaylist.h'
595--- tests/integration/tst_mediaplaylist.h 2015-10-22 17:27:54 +0000
596+++ tests/integration/tst_mediaplaylist.h 2015-11-13 14:50:26 +0000
597@@ -56,6 +56,8 @@
598 void constructDestroyRepeat();
599
600 void addTwoTracksAndVerify();
601+ void insertTracksAtPositionAndVerify();
602+ void moveTrackAndVerify();
603 void addListOfTracksAndVerify();
604 void addLargeListOfTracksAndVerify();
605 void addLargeListOfTracksAtOnceAndVerify();
606@@ -88,6 +90,9 @@
607
608 void waitTrackChange(QMediaPlaylist *playlist);
609 void waitTrackInserted(QMediaPlaylist *playlist);
610+ void waitTrackRemoved(QMediaPlaylist *playlist);
611+ void waitPlaybackModeChange(QMediaPlaylist *playlist,
612+ const std::function<void()>& action);
613
614 // A generic way of getting a signal registered into m_signalsDeque without blocking
615 // which can be used to later check the order of signals that were emitted. Simply call

Subscribers

People subscribed via source and target branches

to all changes: