Merge lp:~phablet-team/qtubuntu-media/bg-playlist-fixes into lp:qtubuntu-media/stable
- bg-playlist-fixes
- Merge into 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 | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jim Hodapp (community) | code | Approve | |
Review via email: mp+276164@code.launchpad.net |
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)
- 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
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 |
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.