1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | //TESTED_COMPONENT=src/multimedia |
30 | |
31 | #include <QtTest/QtTest> |
32 | |
33 | #include <QtCore/qdebug.h> |
34 | #include <QtCore/qbuffer.h> |
35 | #include <QtNetwork/qnetworkconfiguration.h> |
36 | #include <QtNetwork/qnetworkconfigmanager.h> |
37 | |
38 | #include <qabstractvideosurface.h> |
39 | #include <qmediaplayer.h> |
40 | #include <qmediaplayercontrol.h> |
41 | #include <qmediaplaylist.h> |
42 | #include <qmediaservice.h> |
43 | #include <qmediastreamscontrol.h> |
44 | #include <qmedianetworkaccesscontrol.h> |
45 | #include <qvideorenderercontrol.h> |
46 | |
47 | #include "mockmediaserviceprovider.h" |
48 | #include "mockmediaplayerservice.h" |
49 | #include "mockvideosurface.h" |
50 | |
51 | QT_USE_NAMESPACE |
52 | |
53 | class AutoConnection |
54 | { |
55 | public: |
56 | AutoConnection(QObject *sender, const char *signal, QObject *receiver, const char *method) |
57 | : sender(sender), signal(signal), receiver(receiver), method(method) |
58 | { |
59 | QObject::connect(sender, signal, receiver, member: method); |
60 | } |
61 | |
62 | ~AutoConnection() |
63 | { |
64 | QObject::disconnect(sender, signal, receiver, member: method); |
65 | } |
66 | |
67 | private: |
68 | QObject *sender; |
69 | const char *signal; |
70 | QObject *receiver; |
71 | const char *method; |
72 | }; |
73 | |
74 | class tst_QMediaPlayer: public QObject |
75 | { |
76 | Q_OBJECT |
77 | |
78 | public slots: |
79 | void initTestCase(); |
80 | void cleanupTestCase(); |
81 | void init(); |
82 | void cleanup(); |
83 | |
84 | private slots: |
85 | void testNullService_data(); |
86 | void testNullService(); |
87 | void testValid(); |
88 | void testMedia_data(); |
89 | void testMedia(); |
90 | void testDuration_data(); |
91 | void testDuration(); |
92 | void testPosition_data(); |
93 | void testPosition(); |
94 | void testVolume_data(); |
95 | void testVolume(); |
96 | void testMuted_data(); |
97 | void testMuted(); |
98 | void testIsAvailable(); |
99 | void testVideoAvailable_data(); |
100 | void testVideoAvailable(); |
101 | void testBufferStatus_data(); |
102 | void testBufferStatus(); |
103 | void testSeekable_data(); |
104 | void testSeekable(); |
105 | void testPlaybackRate_data(); |
106 | void testPlaybackRate(); |
107 | void testError_data(); |
108 | void testError(); |
109 | void testErrorString_data(); |
110 | void testErrorString(); |
111 | void testService(); |
112 | void testPlay_data(); |
113 | void testPlay(); |
114 | void testPause_data(); |
115 | void testPause(); |
116 | void testStop_data(); |
117 | void testStop(); |
118 | void testMediaStatus_data(); |
119 | void testMediaStatus(); |
120 | void testPlaylist(); |
121 | #ifndef QT_NO_BEARERMANAGEMENT |
122 | void testNetworkAccess(); |
123 | #endif |
124 | void testSetVideoOutput(); |
125 | void testSetVideoOutputNoService(); |
126 | void testSetVideoOutputNoControl(); |
127 | void testSetVideoOutputDestruction(); |
128 | void testPositionPropertyWatch(); |
129 | void debugEnums(); |
130 | void testPlayerFlags(); |
131 | void testDestructor(); |
132 | void testSupportedMimeTypes(); |
133 | void testQrc_data(); |
134 | void testQrc(); |
135 | void testAudioRole(); |
136 | void testCustomAudioRole(); |
137 | |
138 | private: |
139 | void setupCommonTestData(); |
140 | |
141 | MockMediaServiceProvider *mockProvider; |
142 | MockMediaPlayerService *mockService; |
143 | QMediaPlayer *player; |
144 | }; |
145 | |
146 | void tst_QMediaPlayer::setupCommonTestData() |
147 | { |
148 | QTest::addColumn<bool>(name: "valid" ); |
149 | QTest::addColumn<QMediaPlayer::State>(name: "state" ); |
150 | QTest::addColumn<QMediaPlayer::MediaStatus>(name: "status" ); |
151 | QTest::addColumn<QMediaContent>(name: "mediaContent" ); |
152 | QTest::addColumn<qint64>(name: "duration" ); |
153 | QTest::addColumn<qint64>(name: "position" ); |
154 | QTest::addColumn<bool>(name: "seekable" ); |
155 | QTest::addColumn<int>(name: "volume" ); |
156 | QTest::addColumn<bool>(name: "muted" ); |
157 | QTest::addColumn<bool>(name: "videoAvailable" ); |
158 | QTest::addColumn<int>(name: "bufferStatus" ); |
159 | QTest::addColumn<qreal>(name: "playbackRate" ); |
160 | QTest::addColumn<QMediaPlayer::Error>(name: "error" ); |
161 | QTest::addColumn<QString>(name: "errorString" ); |
162 | |
163 | QTest::newRow(dataTag: "invalid" ) << false << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus << |
164 | QMediaContent() << qint64(0) << qint64(0) << false << 0 << false << false << 0 << |
165 | qreal(0) << QMediaPlayer::NoError << QString(); |
166 | QTest::newRow(dataTag: "valid+null" ) << true << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus << |
167 | QMediaContent() << qint64(0) << qint64(0) << false << 0 << false << false << 50 << |
168 | qreal(0) << QMediaPlayer::NoError << QString(); |
169 | QTest::newRow(dataTag: "valid+content+stopped" ) << true << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus << |
170 | QMediaContent(QUrl("file:///some.mp3" )) << qint64(0) << qint64(0) << false << 50 << false << false << 0 << |
171 | qreal(1) << QMediaPlayer::NoError << QString(); |
172 | QTest::newRow(dataTag: "valid+content+playing" ) << true << QMediaPlayer::PlayingState << QMediaPlayer::LoadedMedia << |
173 | QMediaContent(QUrl("file:///some.mp3" )) << qint64(10000) << qint64(10) << true << 50 << true << false << 0 << |
174 | qreal(1) << QMediaPlayer::NoError << QString(); |
175 | QTest::newRow(dataTag: "valid+content+paused" ) << true << QMediaPlayer::PausedState << QMediaPlayer::LoadedMedia << |
176 | QMediaContent(QUrl("file:///some.mp3" )) << qint64(10000) << qint64(10) << true << 50 << true << false << 0 << |
177 | qreal(1) << QMediaPlayer::NoError << QString(); |
178 | QTest::newRow(dataTag: "valud+streaming" ) << true << QMediaPlayer::PlayingState << QMediaPlayer::LoadedMedia << |
179 | QMediaContent(QUrl("http://example.com/stream" )) << qint64(10000) << qint64(10000) << false << 50 << false << true << 0 << |
180 | qreal(1) << QMediaPlayer::NoError << QString(); |
181 | QTest::newRow(dataTag: "valid+error" ) << true << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus << |
182 | QMediaContent(QUrl("http://example.com/stream" )) << qint64(0) << qint64(0) << false << 50 << false << false << 0 << |
183 | qreal(0) << QMediaPlayer::ResourceError << QString("Resource unavailable" ); |
184 | } |
185 | |
186 | void tst_QMediaPlayer::initTestCase() |
187 | { |
188 | qRegisterMetaType<QMediaPlayer::State>(typeName: "QMediaPlayer::State" ); |
189 | qRegisterMetaType<QMediaPlayer::Error>(typeName: "QMediaPlayer::Error" ); |
190 | qRegisterMetaType<QMediaPlayer::MediaStatus>(typeName: "QMediaPlayer::MediaStatus" ); |
191 | qRegisterMetaType<QMediaContent>(typeName: "QMediaContent" ); |
192 | } |
193 | |
194 | void tst_QMediaPlayer::cleanupTestCase() |
195 | { |
196 | } |
197 | |
198 | void tst_QMediaPlayer::init() |
199 | { |
200 | mockService = new MockMediaPlayerService; |
201 | mockProvider = new MockMediaServiceProvider(mockService); |
202 | QMediaServiceProvider::setDefaultServiceProvider(mockProvider); |
203 | |
204 | player = new QMediaPlayer; |
205 | } |
206 | |
207 | void tst_QMediaPlayer::cleanup() |
208 | { |
209 | delete player; |
210 | delete mockProvider; |
211 | delete mockService; |
212 | } |
213 | |
214 | void tst_QMediaPlayer::testNullService_data() |
215 | { |
216 | setupCommonTestData(); |
217 | } |
218 | |
219 | void tst_QMediaPlayer::testNullService() |
220 | { |
221 | mockProvider->service = 0; |
222 | QMediaPlayer player; |
223 | |
224 | const QIODevice *nullDevice = 0; |
225 | |
226 | QCOMPARE(player.media(), QMediaContent()); |
227 | QCOMPARE(player.mediaStream(), nullDevice); |
228 | QCOMPARE(player.state(), QMediaPlayer::StoppedState); |
229 | QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus); |
230 | QCOMPARE(player.duration(), qint64(-1)); |
231 | QCOMPARE(player.position(), qint64(0)); |
232 | QCOMPARE(player.volume(), 0); |
233 | QCOMPARE(player.isMuted(), false); |
234 | QCOMPARE(player.isVideoAvailable(), false); |
235 | QCOMPARE(player.bufferStatus(), 0); |
236 | QCOMPARE(player.isSeekable(), false); |
237 | QCOMPARE(player.playbackRate(), qreal(0)); |
238 | QCOMPARE(player.error(), QMediaPlayer::ServiceMissingError); |
239 | QCOMPARE(player.isAvailable(), false); |
240 | QCOMPARE(player.availability(), QMultimedia::ServiceMissing); |
241 | |
242 | { |
243 | QFETCH(QMediaContent, mediaContent); |
244 | |
245 | QSignalSpy spy(&player, SIGNAL(currentMediaChanged(QMediaContent))); |
246 | QFile file; |
247 | |
248 | player.setMedia(media: mediaContent, stream: &file); |
249 | QCOMPARE(player.currentMedia(), QMediaContent()); |
250 | QCOMPARE(player.media(), mediaContent); |
251 | QCOMPARE(player.mediaStream(), nullDevice); |
252 | QCOMPARE(spy.count(), 0); |
253 | } { |
254 | QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State))); |
255 | QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); |
256 | |
257 | player.play(); |
258 | QCOMPARE(player.state(), QMediaPlayer::StoppedState); |
259 | QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus); |
260 | QCOMPARE(stateSpy.count(), 0); |
261 | QCOMPARE(statusSpy.count(), 0); |
262 | |
263 | player.pause(); |
264 | QCOMPARE(player.state(), QMediaPlayer::StoppedState); |
265 | QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus); |
266 | QCOMPARE(stateSpy.count(), 0); |
267 | QCOMPARE(statusSpy.count(), 0); |
268 | |
269 | player.stop(); |
270 | QCOMPARE(player.state(), QMediaPlayer::StoppedState); |
271 | QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus); |
272 | QCOMPARE(stateSpy.count(), 0); |
273 | QCOMPARE(statusSpy.count(), 0); |
274 | } { |
275 | QFETCH(int, volume); |
276 | QFETCH(bool, muted); |
277 | |
278 | QSignalSpy volumeSpy(&player, SIGNAL(volumeChanged(int))); |
279 | QSignalSpy mutingSpy(&player, SIGNAL(mutedChanged(bool))); |
280 | |
281 | player.setVolume(volume); |
282 | QCOMPARE(player.volume(), 0); |
283 | QCOMPARE(volumeSpy.count(), 0); |
284 | |
285 | player.setMuted(muted); |
286 | QCOMPARE(player.isMuted(), false); |
287 | QCOMPARE(mutingSpy.count(), 0); |
288 | } { |
289 | QFETCH(qint64, position); |
290 | |
291 | QSignalSpy spy(&player, SIGNAL(positionChanged(qint64))); |
292 | |
293 | player.setPosition(position); |
294 | QCOMPARE(player.position(), qint64(0)); |
295 | QCOMPARE(spy.count(), 0); |
296 | } { |
297 | QFETCH(qreal, playbackRate); |
298 | |
299 | QSignalSpy spy(&player, SIGNAL(playbackRateChanged(qreal))); |
300 | |
301 | player.setPlaybackRate(playbackRate); |
302 | QCOMPARE(player.playbackRate(), qreal(0)); |
303 | QCOMPARE(spy.count(), 0); |
304 | } { |
305 | QMediaPlaylist playlist; |
306 | player.setPlaylist(&playlist); |
307 | |
308 | QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(QMediaContent))); |
309 | QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); |
310 | |
311 | playlist.addMedia(content: QUrl("http://example.com/stream" )); |
312 | playlist.addMedia(content: QUrl("file:///some.mp3" )); |
313 | |
314 | playlist.setCurrentIndex(0); |
315 | QCOMPARE(playlist.currentIndex(), 0); |
316 | QCOMPARE(player.currentMedia(), QMediaContent()); |
317 | QCOMPARE(player.media().playlist(), &playlist); |
318 | QCOMPARE(mediaSpy.count(), 0); |
319 | QCOMPARE(statusSpy.count(), 0); |
320 | |
321 | playlist.next(); |
322 | QCOMPARE(playlist.currentIndex(), 1); |
323 | QCOMPARE(player.currentMedia(), QMediaContent()); |
324 | QCOMPARE(player.media().playlist(), &playlist); |
325 | QCOMPARE(mediaSpy.count(), 0); |
326 | QCOMPARE(statusSpy.count(), 0); |
327 | } |
328 | } |
329 | |
330 | void tst_QMediaPlayer::testValid() |
331 | { |
332 | /* |
333 | QFETCH(bool, valid); |
334 | |
335 | mockService->setIsValid(valid); |
336 | QCOMPARE(player->isValid(), valid); |
337 | */ |
338 | } |
339 | |
340 | void tst_QMediaPlayer::testMedia_data() |
341 | { |
342 | setupCommonTestData(); |
343 | } |
344 | |
345 | void tst_QMediaPlayer::testMedia() |
346 | { |
347 | QFETCH(QMediaContent, mediaContent); |
348 | |
349 | mockService->setMedia(mediaContent); |
350 | QCOMPARE(player->currentMedia(), mediaContent); |
351 | |
352 | QBuffer stream; |
353 | player->setMedia(media: mediaContent, stream: &stream); |
354 | QCOMPARE(player->currentMedia(), mediaContent); |
355 | QCOMPARE((QBuffer*)player->mediaStream(), &stream); |
356 | } |
357 | |
358 | void tst_QMediaPlayer::testDuration_data() |
359 | { |
360 | setupCommonTestData(); |
361 | } |
362 | |
363 | void tst_QMediaPlayer::testDuration() |
364 | { |
365 | QFETCH(qint64, duration); |
366 | |
367 | mockService->setDuration(duration); |
368 | QVERIFY(player->duration() == duration); |
369 | } |
370 | |
371 | void tst_QMediaPlayer::testPosition_data() |
372 | { |
373 | setupCommonTestData(); |
374 | } |
375 | |
376 | void tst_QMediaPlayer::testPosition() |
377 | { |
378 | QFETCH(bool, valid); |
379 | QFETCH(bool, seekable); |
380 | QFETCH(qint64, position); |
381 | QFETCH(qint64, duration); |
382 | |
383 | mockService->setIsValid(valid); |
384 | mockService->setSeekable(seekable); |
385 | mockService->setPosition(position); |
386 | mockService->setDuration(duration); |
387 | QVERIFY(player->isSeekable() == seekable); |
388 | QVERIFY(player->position() == position); |
389 | QVERIFY(player->duration() == duration); |
390 | |
391 | if (seekable) { |
392 | { QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); |
393 | player->setPosition(position); |
394 | QCOMPARE(player->position(), position); |
395 | QCOMPARE(spy.count(), 0); } |
396 | |
397 | mockService->setPosition(position); |
398 | { QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); |
399 | player->setPosition(0); |
400 | QCOMPARE(player->position(), qint64(0)); |
401 | QCOMPARE(spy.count(), position == 0 ? 0 : 1); } |
402 | |
403 | mockService->setPosition(position); |
404 | { QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); |
405 | player->setPosition(duration); |
406 | QCOMPARE(player->position(), duration); |
407 | QCOMPARE(spy.count(), position == duration ? 0 : 1); } |
408 | |
409 | mockService->setPosition(position); |
410 | { QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); |
411 | player->setPosition(-1); |
412 | QCOMPARE(player->position(), qint64(0)); |
413 | QCOMPARE(spy.count(), position == 0 ? 0 : 1); } |
414 | |
415 | } |
416 | else { |
417 | QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); |
418 | player->setPosition(position); |
419 | |
420 | QCOMPARE(player->position(), position); |
421 | QCOMPARE(spy.count(), 0); |
422 | } |
423 | } |
424 | |
425 | void tst_QMediaPlayer::testVolume_data() |
426 | { |
427 | setupCommonTestData(); |
428 | } |
429 | |
430 | void tst_QMediaPlayer::testVolume() |
431 | { |
432 | QFETCH(bool, valid); |
433 | QFETCH(int, volume); |
434 | |
435 | mockService->setVolume(volume); |
436 | QVERIFY(player->volume() == volume); |
437 | |
438 | if (valid) { |
439 | { QSignalSpy spy(player, SIGNAL(volumeChanged(int))); |
440 | player->setVolume(10); |
441 | QCOMPARE(player->volume(), 10); |
442 | QCOMPARE(spy.count(), 1); } |
443 | |
444 | { QSignalSpy spy(player, SIGNAL(volumeChanged(int))); |
445 | player->setVolume(-1000); |
446 | QCOMPARE(player->volume(), 0); |
447 | QCOMPARE(spy.count(), 1); } |
448 | |
449 | { QSignalSpy spy(player, SIGNAL(volumeChanged(int))); |
450 | player->setVolume(100); |
451 | QCOMPARE(player->volume(), 100); |
452 | QCOMPARE(spy.count(), 1); } |
453 | |
454 | { QSignalSpy spy(player, SIGNAL(volumeChanged(int))); |
455 | player->setVolume(1000); |
456 | QCOMPARE(player->volume(), 100); |
457 | QCOMPARE(spy.count(), 0); } |
458 | } |
459 | } |
460 | |
461 | void tst_QMediaPlayer::testMuted_data() |
462 | { |
463 | setupCommonTestData(); |
464 | } |
465 | |
466 | void tst_QMediaPlayer::testMuted() |
467 | { |
468 | QFETCH(bool, valid); |
469 | QFETCH(bool, muted); |
470 | QFETCH(int, volume); |
471 | |
472 | if (valid) { |
473 | mockService->setMuted(muted); |
474 | mockService->setVolume(volume); |
475 | QVERIFY(player->isMuted() == muted); |
476 | |
477 | QSignalSpy spy(player, SIGNAL(mutedChanged(bool))); |
478 | player->setMuted(!muted); |
479 | QCOMPARE(player->isMuted(), !muted); |
480 | QCOMPARE(player->volume(), volume); |
481 | QCOMPARE(spy.count(), 1); |
482 | } |
483 | } |
484 | |
485 | void tst_QMediaPlayer::testVideoAvailable_data() |
486 | { |
487 | setupCommonTestData(); |
488 | } |
489 | |
490 | void tst_QMediaPlayer::testVideoAvailable() |
491 | { |
492 | QFETCH(bool, videoAvailable); |
493 | |
494 | mockService->setVideoAvailable(videoAvailable); |
495 | QVERIFY(player->isVideoAvailable() == videoAvailable); |
496 | } |
497 | |
498 | void tst_QMediaPlayer::testBufferStatus_data() |
499 | { |
500 | setupCommonTestData(); |
501 | } |
502 | |
503 | void tst_QMediaPlayer::testBufferStatus() |
504 | { |
505 | QFETCH(int, bufferStatus); |
506 | |
507 | mockService->setBufferStatus(bufferStatus); |
508 | QVERIFY(player->bufferStatus() == bufferStatus); |
509 | } |
510 | |
511 | void tst_QMediaPlayer::testSeekable_data() |
512 | { |
513 | setupCommonTestData(); |
514 | } |
515 | |
516 | void tst_QMediaPlayer::testSeekable() |
517 | { |
518 | QFETCH(bool, seekable); |
519 | |
520 | mockService->setSeekable(seekable); |
521 | QVERIFY(player->isSeekable() == seekable); |
522 | } |
523 | |
524 | void tst_QMediaPlayer::testPlaybackRate_data() |
525 | { |
526 | setupCommonTestData(); |
527 | } |
528 | |
529 | void tst_QMediaPlayer::testPlaybackRate() |
530 | { |
531 | QFETCH(bool, valid); |
532 | QFETCH(qreal, playbackRate); |
533 | |
534 | if (valid) { |
535 | mockService->setPlaybackRate(playbackRate); |
536 | QVERIFY(player->playbackRate() == playbackRate); |
537 | |
538 | QSignalSpy spy(player, SIGNAL(playbackRateChanged(qreal))); |
539 | player->setPlaybackRate(playbackRate + 0.5f); |
540 | QCOMPARE(player->playbackRate(), playbackRate + 0.5f); |
541 | QCOMPARE(spy.count(), 1); |
542 | } |
543 | } |
544 | |
545 | void tst_QMediaPlayer::testError_data() |
546 | { |
547 | setupCommonTestData(); |
548 | } |
549 | |
550 | void tst_QMediaPlayer::testError() |
551 | { |
552 | QFETCH(QMediaPlayer::Error, error); |
553 | |
554 | mockService->setError(error); |
555 | QVERIFY(player->error() == error); |
556 | } |
557 | |
558 | void tst_QMediaPlayer::testErrorString_data() |
559 | { |
560 | setupCommonTestData(); |
561 | } |
562 | |
563 | void tst_QMediaPlayer::testErrorString() |
564 | { |
565 | QFETCH(QString, errorString); |
566 | |
567 | mockService->setErrorString(errorString); |
568 | QVERIFY(player->errorString() == errorString); |
569 | } |
570 | |
571 | void tst_QMediaPlayer::testIsAvailable() |
572 | { |
573 | QCOMPARE(player->isAvailable(), true); |
574 | QCOMPARE(player->availability(), QMultimedia::Available); |
575 | } |
576 | |
577 | void tst_QMediaPlayer::testService() |
578 | { |
579 | /* |
580 | QFETCH(bool, valid); |
581 | |
582 | mockService->setIsValid(valid); |
583 | |
584 | if (valid) |
585 | QVERIFY(player->service() != 0); |
586 | else |
587 | QVERIFY(player->service() == 0); |
588 | */ |
589 | } |
590 | |
591 | void tst_QMediaPlayer::testPlay_data() |
592 | { |
593 | setupCommonTestData(); |
594 | } |
595 | |
596 | void tst_QMediaPlayer::testPlay() |
597 | { |
598 | QFETCH(bool, valid); |
599 | QFETCH(QMediaContent, mediaContent); |
600 | QFETCH(QMediaPlayer::State, state); |
601 | |
602 | mockService->setIsValid(valid); |
603 | mockService->setState(state); |
604 | mockService->setMedia(mediaContent); |
605 | QVERIFY(player->state() == state); |
606 | QVERIFY(player->currentMedia() == mediaContent); |
607 | |
608 | QSignalSpy spy(player, SIGNAL(stateChanged(QMediaPlayer::State))); |
609 | |
610 | player->play(); |
611 | |
612 | if (!valid || mediaContent.isNull()) { |
613 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
614 | QCOMPARE(spy.count(), 0); |
615 | } |
616 | else { |
617 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
618 | QCOMPARE(spy.count(), state == QMediaPlayer::PlayingState ? 0 : 1); |
619 | } |
620 | } |
621 | |
622 | void tst_QMediaPlayer::testPause_data() |
623 | { |
624 | setupCommonTestData(); |
625 | } |
626 | |
627 | void tst_QMediaPlayer::testPause() |
628 | { |
629 | QFETCH(bool, valid); |
630 | QFETCH(QMediaContent, mediaContent); |
631 | QFETCH(QMediaPlayer::State, state); |
632 | |
633 | mockService->setIsValid(valid); |
634 | mockService->setState(state); |
635 | mockService->setMedia(mediaContent); |
636 | QVERIFY(player->state() == state); |
637 | QVERIFY(player->currentMedia() == mediaContent); |
638 | |
639 | QSignalSpy spy(player, SIGNAL(stateChanged(QMediaPlayer::State))); |
640 | |
641 | player->pause(); |
642 | |
643 | if (!valid || mediaContent.isNull()) { |
644 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
645 | QCOMPARE(spy.count(), 0); |
646 | } |
647 | else { |
648 | QCOMPARE(player->state(), QMediaPlayer::PausedState); |
649 | QCOMPARE(spy.count(), state == QMediaPlayer::PausedState ? 0 : 1); |
650 | } |
651 | } |
652 | |
653 | void tst_QMediaPlayer::testStop_data() |
654 | { |
655 | setupCommonTestData(); |
656 | } |
657 | |
658 | void tst_QMediaPlayer::testStop() |
659 | { |
660 | QFETCH(QMediaContent, mediaContent); |
661 | QFETCH(QMediaPlayer::State, state); |
662 | |
663 | mockService->setState(state); |
664 | mockService->setMedia(mediaContent); |
665 | QVERIFY(player->state() == state); |
666 | QVERIFY(player->currentMedia() == mediaContent); |
667 | |
668 | QSignalSpy spy(player, SIGNAL(stateChanged(QMediaPlayer::State))); |
669 | |
670 | player->stop(); |
671 | |
672 | if (mediaContent.isNull() || state == QMediaPlayer::StoppedState) { |
673 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
674 | QCOMPARE(spy.count(), 0); |
675 | } |
676 | else { |
677 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
678 | QCOMPARE(spy.count(), 1); |
679 | } |
680 | } |
681 | |
682 | void tst_QMediaPlayer::testMediaStatus_data() |
683 | { |
684 | setupCommonTestData(); |
685 | } |
686 | |
687 | void tst_QMediaPlayer::testMediaStatus() |
688 | { |
689 | QFETCH(int, bufferStatus); |
690 | int bufferSignals = 0; |
691 | |
692 | player->setNotifyInterval(10); |
693 | |
694 | mockService->setMediaStatus(QMediaPlayer::NoMedia); |
695 | mockService->setBufferStatus(bufferStatus); |
696 | |
697 | AutoConnection connection( |
698 | player, SIGNAL(bufferStatusChanged(int)), |
699 | &QTestEventLoop::instance(), SLOT(exitLoop())); |
700 | |
701 | QSignalSpy statusSpy(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); |
702 | QSignalSpy bufferSpy(player, SIGNAL(bufferStatusChanged(int))); |
703 | |
704 | QCOMPARE(player->mediaStatus(), QMediaPlayer::NoMedia); |
705 | |
706 | mockService->setMediaStatus(QMediaPlayer::LoadingMedia); |
707 | QCOMPARE(player->mediaStatus(), QMediaPlayer::LoadingMedia); |
708 | QCOMPARE(statusSpy.count(), 1); |
709 | |
710 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), |
711 | QMediaPlayer::LoadingMedia); |
712 | |
713 | mockService->setMediaStatus(QMediaPlayer::LoadedMedia); |
714 | QCOMPARE(player->mediaStatus(), QMediaPlayer::LoadedMedia); |
715 | QCOMPARE(statusSpy.count(), 2); |
716 | |
717 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), |
718 | QMediaPlayer::LoadedMedia); |
719 | |
720 | // Verify the bufferStatusChanged() signal isn't being emitted. |
721 | QTestEventLoop::instance().enterLoop(secs: 1); |
722 | QCOMPARE(bufferSpy.count(), 0); |
723 | |
724 | mockService->setMediaStatus(QMediaPlayer::StalledMedia); |
725 | QCOMPARE(player->mediaStatus(), QMediaPlayer::StalledMedia); |
726 | QCOMPARE(statusSpy.count(), 3); |
727 | |
728 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), |
729 | QMediaPlayer::StalledMedia); |
730 | |
731 | // Verify the bufferStatusChanged() signal is being emitted. |
732 | QTestEventLoop::instance().enterLoop(secs: 1); |
733 | QVERIFY(bufferSpy.count() > bufferSignals); |
734 | QCOMPARE(bufferSpy.last().value(0).toInt(), bufferStatus); |
735 | bufferSignals = bufferSpy.count(); |
736 | |
737 | mockService->setMediaStatus(QMediaPlayer::BufferingMedia); |
738 | QCOMPARE(player->mediaStatus(), QMediaPlayer::BufferingMedia); |
739 | QCOMPARE(statusSpy.count(), 4); |
740 | |
741 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), |
742 | QMediaPlayer::BufferingMedia); |
743 | |
744 | // Verify the bufferStatusChanged() signal is being emitted. |
745 | QTestEventLoop::instance().enterLoop(secs: 1); |
746 | QVERIFY(bufferSpy.count() > bufferSignals); |
747 | QCOMPARE(bufferSpy.last().value(0).toInt(), bufferStatus); |
748 | bufferSignals = bufferSpy.count(); |
749 | |
750 | mockService->setMediaStatus(QMediaPlayer::BufferedMedia); |
751 | QCOMPARE(player->mediaStatus(), QMediaPlayer::BufferedMedia); |
752 | QCOMPARE(statusSpy.count(), 5); |
753 | |
754 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), |
755 | QMediaPlayer::BufferedMedia); |
756 | |
757 | // Verify the bufferStatusChanged() signal isn't being emitted. |
758 | QTestEventLoop::instance().enterLoop(secs: 1); |
759 | QCOMPARE(bufferSpy.count(), bufferSignals); |
760 | |
761 | mockService->setMediaStatus(QMediaPlayer::EndOfMedia); |
762 | QCOMPARE(player->mediaStatus(), QMediaPlayer::EndOfMedia); |
763 | QCOMPARE(statusSpy.count(), 6); |
764 | |
765 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), |
766 | QMediaPlayer::EndOfMedia); |
767 | } |
768 | |
769 | void tst_QMediaPlayer::testPlaylist() |
770 | { |
771 | QMediaContent content0(QUrl(QLatin1String("test://audio/song1.mp3" ))); |
772 | QMediaContent content1(QUrl(QLatin1String("test://audio/song2.mp3" ))); |
773 | QMediaContent content2(QUrl(QLatin1String("test://video/movie1.mp4" ))); |
774 | QMediaContent content3(QUrl(QLatin1String("test://video/movie2.mp4" ))); |
775 | QMediaContent content4(QUrl(QLatin1String("test://image/photo.jpg" ))); |
776 | |
777 | mockService->setIsValid(true); |
778 | mockService->setState(state: QMediaPlayer::StoppedState, status: QMediaPlayer::NoMedia); |
779 | |
780 | QMediaPlaylist *playlist = new QMediaPlaylist; |
781 | player->setPlaylist(playlist); |
782 | QCOMPARE(player->media().playlist(), playlist); |
783 | |
784 | QSignalSpy stateSpy(player, SIGNAL(stateChanged(QMediaPlayer::State))); |
785 | QSignalSpy mediaSpy(player, SIGNAL(currentMediaChanged(QMediaContent))); |
786 | |
787 | // Test the player does nothing with an empty playlist attached. |
788 | player->play(); |
789 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
790 | QCOMPARE(player->currentMedia(), QMediaContent()); |
791 | QCOMPARE(stateSpy.count(), 0); |
792 | QCOMPARE(mediaSpy.count(), 0); |
793 | |
794 | playlist->addMedia(content: content0); |
795 | playlist->addMedia(content: content1); |
796 | playlist->addMedia(content: content2); |
797 | playlist->addMedia(content: content3); |
798 | |
799 | // Test changing the playlist position, changes the current media, but not the playing state. |
800 | playlist->setCurrentIndex(1); |
801 | QCOMPARE(player->currentMedia(), content1); |
802 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
803 | QCOMPARE(stateSpy.count(), 0); |
804 | QCOMPARE(mediaSpy.count(), 1); |
805 | |
806 | // Test playing starts with the current media. |
807 | player->play(); |
808 | QCOMPARE(player->currentMedia(), content1); |
809 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
810 | QCOMPARE(stateSpy.count(), 1); |
811 | QCOMPARE(mediaSpy.count(), 1); |
812 | |
813 | // Test pausing doesn't change the current media. |
814 | player->pause(); |
815 | QCOMPARE(player->currentMedia(), content1); |
816 | QCOMPARE(player->state(), QMediaPlayer::PausedState); |
817 | QCOMPARE(stateSpy.count(), 2); |
818 | QCOMPARE(mediaSpy.count(), 1); |
819 | |
820 | // Test stopping doesn't change the current media. |
821 | player->stop(); |
822 | QCOMPARE(player->currentMedia(), content1); |
823 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
824 | QCOMPARE(stateSpy.count(), 3); |
825 | QCOMPARE(mediaSpy.count(), 1); |
826 | |
827 | // Test when the player service reaches the end of the current media, the player moves onto |
828 | // the next item without stopping. |
829 | player->play(); |
830 | QCOMPARE(player->currentMedia(), content1); |
831 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
832 | QCOMPARE(stateSpy.count(), 4); |
833 | QCOMPARE(mediaSpy.count(), 1); |
834 | |
835 | mockService->setState(state: QMediaPlayer::StoppedState, status: QMediaPlayer::EndOfMedia); |
836 | QCOMPARE(player->currentMedia(), content2); |
837 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
838 | QCOMPARE(stateSpy.count(), 4); |
839 | QCOMPARE(mediaSpy.count(), 2); |
840 | |
841 | // Test skipping the current media doesn't change the state. |
842 | playlist->next(); |
843 | QCOMPARE(player->currentMedia(), content3); |
844 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
845 | QCOMPARE(stateSpy.count(), 4); |
846 | QCOMPARE(mediaSpy.count(), 3); |
847 | |
848 | // Test changing the current media while paused doesn't change the state. |
849 | player->pause(); |
850 | mockService->setMediaStatus(QMediaPlayer::BufferedMedia); |
851 | QCOMPARE(player->currentMedia(), content3); |
852 | QCOMPARE(player->state(), QMediaPlayer::PausedState); |
853 | QCOMPARE(stateSpy.count(), 5); |
854 | QCOMPARE(mediaSpy.count(), 3); |
855 | |
856 | playlist->previous(); |
857 | QCOMPARE(player->currentMedia(), content2); |
858 | QCOMPARE(player->state(), QMediaPlayer::PausedState); |
859 | QCOMPARE(stateSpy.count(), 5); |
860 | QCOMPARE(mediaSpy.count(), 4); |
861 | |
862 | // Test changing the current media while stopped doesn't change the state. |
863 | player->stop(); |
864 | mockService->setMediaStatus(QMediaPlayer::LoadedMedia); |
865 | QCOMPARE(player->currentMedia(), content2); |
866 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
867 | QCOMPARE(stateSpy.count(), 6); |
868 | QCOMPARE(mediaSpy.count(), 4); |
869 | |
870 | playlist->next(); |
871 | QCOMPARE(player->currentMedia(), content3); |
872 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
873 | QCOMPARE(stateSpy.count(), 6); |
874 | QCOMPARE(mediaSpy.count(), 5); |
875 | |
876 | // Test the player is stopped and the current media cleared when it reaches the end of the last |
877 | // item in the playlist. |
878 | player->play(); |
879 | QCOMPARE(player->currentMedia(), content3); |
880 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
881 | QCOMPARE(stateSpy.count(), 7); |
882 | QCOMPARE(mediaSpy.count(), 5); |
883 | |
884 | // Double up the signals to ensure some noise doesn't destabalize things. |
885 | mockService->setState(state: QMediaPlayer::StoppedState, status: QMediaPlayer::EndOfMedia); |
886 | mockService->setState(state: QMediaPlayer::StoppedState, status: QMediaPlayer::EndOfMedia); |
887 | QCOMPARE(player->currentMedia(), QMediaContent()); |
888 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
889 | QCOMPARE(stateSpy.count(), 8); |
890 | QCOMPARE(mediaSpy.count(), 6); |
891 | |
892 | // Test starts playing from the start of the playlist if there is no current media selected. |
893 | player->play(); |
894 | QCOMPARE(player->currentMedia(), content0); |
895 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
896 | QCOMPARE(stateSpy.count(), 9); |
897 | // one notification is for playlist and another is for the first media in the playlist |
898 | QCOMPARE(mediaSpy.count(), 8); |
899 | |
900 | // Test deleting the playlist stops the player and clears the media it set. |
901 | delete playlist; |
902 | QCOMPARE(player->currentMedia(), QMediaContent()); |
903 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
904 | QCOMPARE(stateSpy.count(), 10); |
905 | QCOMPARE(mediaSpy.count(), 9); |
906 | |
907 | // Test the player works as normal with the playlist removed. |
908 | player->play(); |
909 | QCOMPARE(player->currentMedia(), QMediaContent()); |
910 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
911 | QCOMPARE(stateSpy.count(), 10); |
912 | QCOMPARE(mediaSpy.count(), 9); |
913 | |
914 | player->setMedia(media: content1); |
915 | player->play(); |
916 | |
917 | QCOMPARE(player->currentMedia(), content1); |
918 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
919 | QCOMPARE(stateSpy.count(), 11); |
920 | QCOMPARE(mediaSpy.count(), 10); |
921 | |
922 | // Test the player can bind to playlist again |
923 | playlist = new QMediaPlaylist; |
924 | player->setPlaylist(playlist); |
925 | |
926 | QCOMPARE(player->currentMedia(), QMediaContent()); |
927 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
928 | |
929 | playlist->addMedia(content: content0); |
930 | playlist->addMedia(content: content1); |
931 | playlist->addMedia(content: content2); |
932 | playlist->addMedia(content: content3); |
933 | |
934 | playlist->setCurrentIndex(1); |
935 | QCOMPARE(player->currentMedia(), content1); |
936 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
937 | |
938 | // Test attaching the new playlist, |
939 | // player should detach the current one |
940 | QMediaPlaylist *playlist2 = new QMediaPlaylist; |
941 | playlist2->addMedia(content: content1); |
942 | playlist2->addMedia(content: content2); |
943 | playlist2->addMedia(content: content3); |
944 | playlist2->setCurrentIndex(2); |
945 | |
946 | player->play(); |
947 | player->setPlaylist(playlist2); |
948 | QCOMPARE(player->currentMedia(), playlist2->currentMedia()); |
949 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
950 | |
951 | playlist2->setCurrentIndex(1); |
952 | QCOMPARE(player->currentMedia(), playlist2->currentMedia()); |
953 | |
954 | { |
955 | QMediaPlaylist playlist; |
956 | playlist.addMedia(content: content1); |
957 | playlist.addMedia(content: content2); |
958 | playlist.addMedia(content: content3); |
959 | playlist.setCurrentIndex(1); |
960 | |
961 | // playlist resets to the first item |
962 | player->setPlaylist(&playlist); |
963 | QCOMPARE(player->playlist(), &playlist); |
964 | QCOMPARE(player->currentMedia(), content1); |
965 | } //playlist should be detached now |
966 | |
967 | QVERIFY(player->playlist() == 0); |
968 | QCOMPARE(player->currentMedia(), QMediaContent()); |
969 | |
970 | // Test when the player service encounters an invalid media, the player moves onto |
971 | // the next item without stopping |
972 | { |
973 | QSignalSpy ss(player, SIGNAL(stateChanged(QMediaPlayer::State))); |
974 | QSignalSpy ms(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); |
975 | |
976 | // playlist index is set to 0 when it is loaded into media player |
977 | player->setPlaylist(playlist); |
978 | player->play(); |
979 | QCOMPARE(ss.count(), 1); |
980 | QCOMPARE(ms.count(), 1); |
981 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(ms.last().value(0)), QMediaPlayer::LoadingMedia); |
982 | ms.clear(); |
983 | |
984 | mockService->setState(state: QMediaPlayer::StoppedState, status: QMediaPlayer::InvalidMedia); |
985 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
986 | QCOMPARE(player->mediaStatus(), QMediaPlayer::LoadingMedia); |
987 | QCOMPARE(ss.count(), 1); |
988 | QCOMPARE(ms.count(), 2); |
989 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(ms.at(0).value(0)), QMediaPlayer::InvalidMedia); |
990 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(ms.at(1).value(0)), QMediaPlayer::LoadingMedia); |
991 | |
992 | // NOTE: status should begin transitioning through to BufferedMedia. |
993 | QCOMPARE(player->currentMedia(), content1); |
994 | } |
995 | |
996 | delete playlist; |
997 | delete playlist2; |
998 | } |
999 | |
1000 | void tst_QMediaPlayer::testPlayerFlags() |
1001 | { |
1002 | MockMediaServiceProvider provider(0, true); |
1003 | QMediaPlayer::Flag flags = QMediaPlayer::LowLatency; |
1004 | |
1005 | QMediaServiceProviderHint::Feature feature; |
1006 | |
1007 | if (flags & QMediaPlayer::LowLatency) |
1008 | { |
1009 | /* if the flag is low latency set the low latency play back for the service provider */ |
1010 | feature = QMediaServiceProviderHint::LowLatencyPlayback; |
1011 | const QByteArray service(Q_MEDIASERVICE_MEDIAPLAYER); |
1012 | const QMediaServiceProviderHint providerHint(feature); |
1013 | /* request service for the service provider */ |
1014 | provider.requestService(service,providerHint); |
1015 | |
1016 | /* Constructs a SupportedFeatures media service provider hint. */ |
1017 | QMediaServiceProviderHint servicepro(feature); |
1018 | |
1019 | /* compare the flag value */ |
1020 | QVERIFY(servicepro.features() == QMediaServiceProviderHint::LowLatencyPlayback); |
1021 | } |
1022 | |
1023 | /* The player is expected to play QIODevice based streams. |
1024 | If passed to QMediaPlayer constructor, |
1025 | the service supporting streams playback will be chosen. */ |
1026 | flags = QMediaPlayer::StreamPlayback; |
1027 | /* Construct a QMediaPlayer that uses the playback service from provider, |
1028 | parented to parent and with flags.*/ |
1029 | |
1030 | if (flags & QMediaPlayer::StreamPlayback) |
1031 | { |
1032 | /* if the flag is stream play back set the stream play back for the service provider */ |
1033 | feature = QMediaServiceProviderHint::StreamPlayback; |
1034 | const QByteArray service(Q_MEDIASERVICE_MEDIAPLAYER); |
1035 | const QMediaServiceProviderHint providerHint(feature); |
1036 | |
1037 | /* request service for the service provider */ |
1038 | provider.requestService(service,providerHint); |
1039 | |
1040 | /* Constructs a SupportedFeatures media service provider hint. */ |
1041 | QMediaServiceProviderHint servicepro(feature); |
1042 | |
1043 | /* compare the flag value */ |
1044 | QVERIFY(servicepro.features() == QMediaServiceProviderHint::StreamPlayback); |
1045 | } |
1046 | } |
1047 | |
1048 | void tst_QMediaPlayer::testDestructor() |
1049 | { |
1050 | //don't use the same service as tst_QMediaPlayer::player |
1051 | mockProvider->service = new MockMediaPlayerService; |
1052 | mockProvider->deleteServiceOnRelease = true; |
1053 | |
1054 | /* create an object for player */ |
1055 | QMediaPlayer *victim = new QMediaPlayer; |
1056 | |
1057 | /* check whether the object is created */ |
1058 | QVERIFY(victim); |
1059 | |
1060 | /* delete the instance (a crash is a failure :) */ |
1061 | delete victim; |
1062 | |
1063 | //service is released |
1064 | QVERIFY(mockProvider->service == 0); |
1065 | |
1066 | mockProvider->deleteServiceOnRelease = false; |
1067 | } |
1068 | |
1069 | #ifndef QT_NO_BEARERMANAGEMENT |
1070 | void tst_QMediaPlayer::testNetworkAccess() |
1071 | { |
1072 | QNetworkConfigurationManager manager; |
1073 | QList<QNetworkConfiguration> configs = manager.allConfigurations(); |
1074 | |
1075 | if (configs.count() >= 1) { |
1076 | QSignalSpy spy(player, SIGNAL(networkConfigurationChanged(QNetworkConfiguration))); |
1077 | int index = qFloor(v: (configs.count())/2); |
1078 | player->setNetworkConfigurations(configs); |
1079 | mockService->selectCurrentConfiguration(config: configs.at(i: index)); |
1080 | |
1081 | QVERIFY(spy.count() == 1); |
1082 | QList<QVariant> args = spy.takeFirst(); |
1083 | QNetworkConfiguration config = args.at(i: 0).value<QNetworkConfiguration>(); |
1084 | QCOMPARE(config.identifier() , configs.at(index).identifier()); |
1085 | QCOMPARE(player->currentNetworkConfiguration().identifier() , config.identifier()); |
1086 | } |
1087 | |
1088 | // invalidate current network configuration |
1089 | QSignalSpy spy(player, SIGNAL(networkConfigurationChanged(QNetworkConfiguration))); |
1090 | mockService->selectCurrentConfiguration(config: QNetworkConfiguration()); |
1091 | QVERIFY(spy.count() == 1); |
1092 | QList<QVariant> args = spy.takeFirst(); |
1093 | QNetworkConfiguration config = args.at(i: 0).value<QNetworkConfiguration>(); |
1094 | QVERIFY(config.isValid() == false); |
1095 | QVERIFY(player->currentNetworkConfiguration().isValid() == false); |
1096 | } |
1097 | #endif |
1098 | |
1099 | void tst_QMediaPlayer::testSetVideoOutput() |
1100 | { |
1101 | MockVideoSurface surface; |
1102 | |
1103 | player->setVideoOutput(reinterpret_cast<QVideoWidget *>(0)); |
1104 | player->setVideoOutput(reinterpret_cast<QGraphicsVideoItem *>(0)); |
1105 | |
1106 | QCOMPARE(mockService->rendererRef, 0); |
1107 | |
1108 | player->setVideoOutput(&surface); |
1109 | QVERIFY(mockService->rendererControl->surface() == &surface); |
1110 | QCOMPARE(mockService->rendererRef, 1); |
1111 | |
1112 | player->setVideoOutput(reinterpret_cast<QAbstractVideoSurface *>(0)); |
1113 | QVERIFY(mockService->rendererControl->surface() == 0); |
1114 | |
1115 | //rendererControl is released |
1116 | QCOMPARE(mockService->rendererRef, 0); |
1117 | |
1118 | player->setVideoOutput(&surface); |
1119 | QVERIFY(mockService->rendererControl->surface() == &surface); |
1120 | QCOMPARE(mockService->rendererRef, 1); |
1121 | |
1122 | player->setVideoOutput(reinterpret_cast<QVideoWidget *>(0)); |
1123 | QVERIFY(mockService->rendererControl->surface() == 0); |
1124 | //rendererControl is released |
1125 | QCOMPARE(mockService->rendererRef, 0); |
1126 | |
1127 | player->setVideoOutput(&surface); |
1128 | QVERIFY(mockService->rendererControl->surface() == &surface); |
1129 | QCOMPARE(mockService->rendererRef, 1); |
1130 | } |
1131 | |
1132 | |
1133 | void tst_QMediaPlayer::testSetVideoOutputNoService() |
1134 | { |
1135 | MockVideoSurface surface; |
1136 | |
1137 | MockMediaServiceProvider provider(0, true); |
1138 | QMediaServiceProvider::setDefaultServiceProvider(&provider); |
1139 | QMediaPlayer player; |
1140 | |
1141 | player.setVideoOutput(&surface); |
1142 | // Nothing we can verify here other than it doesn't assert. |
1143 | } |
1144 | |
1145 | void tst_QMediaPlayer::testSetVideoOutputNoControl() |
1146 | { |
1147 | MockVideoSurface surface; |
1148 | |
1149 | MockMediaPlayerService service; |
1150 | service.rendererRef = 1; |
1151 | |
1152 | MockMediaServiceProvider provider(&service); |
1153 | QMediaServiceProvider::setDefaultServiceProvider(&provider); |
1154 | QMediaPlayer player; |
1155 | |
1156 | player.setVideoOutput(&surface); |
1157 | QVERIFY(service.rendererControl->surface() == 0); |
1158 | } |
1159 | |
1160 | void tst_QMediaPlayer::testSetVideoOutputDestruction() |
1161 | { |
1162 | MockVideoSurface surface; |
1163 | { |
1164 | QMediaPlayer player; |
1165 | player.setVideoOutput(&surface); |
1166 | QVERIFY(mockService->rendererControl->surface() == &surface); |
1167 | QCOMPARE(mockService->rendererRef, 1); |
1168 | } |
1169 | QVERIFY(mockService->rendererControl->surface() == 0); |
1170 | QCOMPARE(mockService->rendererRef, 0); |
1171 | } |
1172 | |
1173 | void tst_QMediaPlayer::testPositionPropertyWatch() |
1174 | { |
1175 | QMediaContent content0(QUrl(QLatin1String("test://audio/song1.mp3" ))); |
1176 | QMediaContent content1(QUrl(QLatin1String("test://audio/song2.mp3" ))); |
1177 | |
1178 | mockService->setIsValid(true); |
1179 | mockService->setState(state: QMediaPlayer::StoppedState, status: QMediaPlayer::NoMedia); |
1180 | |
1181 | QMediaPlaylist *playlist = new QMediaPlaylist; |
1182 | |
1183 | playlist->addMedia(content: content0); |
1184 | playlist->addMedia(content: content1); |
1185 | |
1186 | player->setPlaylist(playlist); |
1187 | player->setNotifyInterval(5); |
1188 | |
1189 | player->play(); |
1190 | QSignalSpy positionSpy(player, SIGNAL(positionChanged(qint64))); |
1191 | playlist->next(); |
1192 | QCOMPARE(player->state(), QMediaPlayer::PlayingState); |
1193 | QTRY_VERIFY(positionSpy.count() > 0); |
1194 | |
1195 | playlist->next(); |
1196 | QCOMPARE(player->state(), QMediaPlayer::StoppedState); |
1197 | |
1198 | positionSpy.clear(); |
1199 | QTRY_COMPARE(positionSpy.count(), 0); |
1200 | |
1201 | delete playlist; |
1202 | } |
1203 | |
1204 | void tst_QMediaPlayer::debugEnums() |
1205 | { |
1206 | QTest::ignoreMessage(type: QtDebugMsg, message: "QMediaPlayer::PlayingState" ); |
1207 | qDebug() << QMediaPlayer::PlayingState; |
1208 | QTest::ignoreMessage(type: QtDebugMsg, message: "QMediaPlayer::NoMedia" ); |
1209 | qDebug() << QMediaPlayer::NoMedia; |
1210 | QTest::ignoreMessage(type: QtDebugMsg, message: "QMediaPlayer::NetworkError" ); |
1211 | qDebug() << QMediaPlayer::NetworkError; |
1212 | } |
1213 | |
1214 | void tst_QMediaPlayer::testSupportedMimeTypes() |
1215 | { |
1216 | QStringList mimeList = QMediaPlayer::supportedMimeTypes(flags: QMediaPlayer::LowLatency); |
1217 | |
1218 | // This is empty on some platforms, and not on others, so can't test something here at the moment. |
1219 | } |
1220 | |
1221 | void tst_QMediaPlayer::testQrc_data() |
1222 | { |
1223 | QTest::addColumn<QMediaContent>(name: "mediaContent" ); |
1224 | QTest::addColumn<QMediaPlayer::MediaStatus>(name: "status" ); |
1225 | QTest::addColumn<QMediaPlayer::Error>(name: "error" ); |
1226 | QTest::addColumn<int>(name: "errorCount" ); |
1227 | QTest::addColumn<bool>(name: "hasStreamFeature" ); |
1228 | QTest::addColumn<QString>(name: "backendMediaContentScheme" ); |
1229 | QTest::addColumn<bool>(name: "backendHasStream" ); |
1230 | |
1231 | QTest::newRow(dataTag: "invalid" ) << QMediaContent(QUrl(QLatin1String("qrc:/invalid.mp3" ))) |
1232 | << QMediaPlayer::InvalidMedia |
1233 | << QMediaPlayer::ResourceError |
1234 | << 1 // error count |
1235 | << false // No StreamPlayback support |
1236 | << QString() // backend should not have got any media (empty URL scheme) |
1237 | << false; // backend should not have got any stream |
1238 | |
1239 | QTest::newRow(dataTag: "valid+nostream" ) << QMediaContent(QUrl(QLatin1String("qrc:/testdata/nokia-tune.mp3" ))) |
1240 | << QMediaPlayer::LoadingMedia |
1241 | << QMediaPlayer::NoError |
1242 | << 0 // error count |
1243 | << false // No StreamPlayback support |
1244 | << QStringLiteral("file" ) // backend should have a got a temporary file |
1245 | << false; // backend should not have got any stream |
1246 | |
1247 | QTest::newRow(dataTag: "valid+stream" ) << QMediaContent(QUrl(QLatin1String("qrc:/testdata/nokia-tune.mp3" ))) |
1248 | << QMediaPlayer::LoadingMedia |
1249 | << QMediaPlayer::NoError |
1250 | << 0 // error count |
1251 | << true // StreamPlayback support |
1252 | << QStringLiteral("qrc" ) |
1253 | << true; // backend should have got a stream (QFile opened from the resource) |
1254 | } |
1255 | |
1256 | void tst_QMediaPlayer::testQrc() |
1257 | { |
1258 | QFETCH(QMediaContent, mediaContent); |
1259 | QFETCH(QMediaPlayer::MediaStatus, status); |
1260 | QFETCH(QMediaPlayer::Error, error); |
1261 | QFETCH(int, errorCount); |
1262 | QFETCH(bool, hasStreamFeature); |
1263 | QFETCH(QString, backendMediaContentScheme); |
1264 | QFETCH(bool, backendHasStream); |
1265 | |
1266 | if (hasStreamFeature) |
1267 | mockProvider->setSupportedFeatures(QMediaServiceProviderHint::StreamPlayback); |
1268 | |
1269 | QMediaPlayer player; |
1270 | |
1271 | mockService->setState(state: QMediaPlayer::PlayingState, status: QMediaPlayer::NoMedia); |
1272 | |
1273 | QSignalSpy mediaSpy(&player, SIGNAL(currentMediaChanged(QMediaContent))); |
1274 | QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); |
1275 | QSignalSpy errorSpy(&player, SIGNAL(error(QMediaPlayer::Error))); |
1276 | |
1277 | player.setMedia(media: mediaContent); |
1278 | |
1279 | QTRY_COMPARE(player.mediaStatus(), status); |
1280 | QCOMPARE(statusSpy.count(), 1); |
1281 | QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), status); |
1282 | |
1283 | QCOMPARE(player.media(), mediaContent); |
1284 | QCOMPARE(player.currentMedia(), mediaContent); |
1285 | QCOMPARE(mediaSpy.count(), 1); |
1286 | QCOMPARE(qvariant_cast<QMediaContent>(mediaSpy.last().value(0)), mediaContent); |
1287 | |
1288 | QCOMPARE(player.error(), error); |
1289 | QCOMPARE(errorSpy.count(), errorCount); |
1290 | if (errorCount > 0) { |
1291 | QCOMPARE(qvariant_cast<QMediaPlayer::Error>(errorSpy.last().value(0)), error); |
1292 | QVERIFY(!player.errorString().isEmpty()); |
1293 | } |
1294 | |
1295 | // Check the media actually passed to the backend |
1296 | QCOMPARE(mockService->mockControl->media().request().url().scheme(), backendMediaContentScheme); |
1297 | QCOMPARE(bool(mockService->mockControl->mediaStream()), backendHasStream); |
1298 | } |
1299 | |
1300 | void tst_QMediaPlayer::testAudioRole() |
1301 | { |
1302 | { |
1303 | mockService->setHasAudioRole(false); |
1304 | QMediaPlayer player; |
1305 | |
1306 | QCOMPARE(player.audioRole(), QAudio::UnknownRole); |
1307 | QVERIFY(player.supportedAudioRoles().isEmpty()); |
1308 | |
1309 | QSignalSpy spy(&player, SIGNAL(audioRoleChanged(QAudio::Role))); |
1310 | player.setAudioRole(QAudio::MusicRole); |
1311 | QCOMPARE(player.audioRole(), QAudio::UnknownRole); |
1312 | QCOMPARE(spy.count(), 0); |
1313 | } |
1314 | |
1315 | { |
1316 | mockService->reset(); |
1317 | mockService->setHasAudioRole(true); |
1318 | QMediaPlayer player; |
1319 | QSignalSpy spy(&player, SIGNAL(audioRoleChanged(QAudio::Role))); |
1320 | |
1321 | QCOMPARE(player.audioRole(), QAudio::UnknownRole); |
1322 | QVERIFY(!player.supportedAudioRoles().isEmpty()); |
1323 | |
1324 | player.setAudioRole(QAudio::MusicRole); |
1325 | QCOMPARE(player.audioRole(), QAudio::MusicRole); |
1326 | QCOMPARE(mockService->mockAudioRoleControl->audioRole(), QAudio::MusicRole); |
1327 | QCOMPARE(spy.count(), 1); |
1328 | QCOMPARE(qvariant_cast<QAudio::Role>(spy.last().value(0)), QAudio::MusicRole); |
1329 | |
1330 | spy.clear(); |
1331 | |
1332 | player.setProperty(name: "audioRole" , value: QVariant::fromValue(value: QAudio::AlarmRole)); |
1333 | QCOMPARE(qvariant_cast<QAudio::Role>(player.property("audioRole" )), QAudio::AlarmRole); |
1334 | QCOMPARE(mockService->mockAudioRoleControl->audioRole(), QAudio::AlarmRole); |
1335 | QCOMPARE(spy.count(), 1); |
1336 | QCOMPARE(qvariant_cast<QAudio::Role>(spy.last().value(0)), QAudio::AlarmRole); |
1337 | } |
1338 | } |
1339 | |
1340 | void tst_QMediaPlayer::testCustomAudioRole() |
1341 | { |
1342 | { |
1343 | mockService->setHasCustomAudioRole(false); |
1344 | QMediaPlayer player; |
1345 | |
1346 | QVERIFY(player.customAudioRole().isEmpty()); |
1347 | QVERIFY(player.supportedCustomAudioRoles().isEmpty()); |
1348 | |
1349 | QSignalSpy spyRole(&player, SIGNAL(audioRoleChanged(QAudio::Role))); |
1350 | QSignalSpy spyCustomRole(&player, SIGNAL(customAudioRoleChanged(const QString &))); |
1351 | player.setCustomAudioRole(QStringLiteral("customRole" )); |
1352 | QCOMPARE(player.audioRole(), QAudio::UnknownRole); |
1353 | QVERIFY(player.customAudioRole().isEmpty()); |
1354 | QCOMPARE(spyRole.count(), 0); |
1355 | QCOMPARE(spyCustomRole.count(), 0); |
1356 | } |
1357 | |
1358 | { |
1359 | mockService->reset(); |
1360 | mockService->setHasAudioRole(false); |
1361 | QMediaPlayer player; |
1362 | |
1363 | QVERIFY(player.customAudioRole().isEmpty()); |
1364 | QVERIFY(player.supportedCustomAudioRoles().isEmpty()); |
1365 | |
1366 | QSignalSpy spyRole(&player, SIGNAL(audioRoleChanged(QAudio::Role))); |
1367 | QSignalSpy spyCustomRole(&player, SIGNAL(customAudioRoleChanged(const QString &))); |
1368 | player.setCustomAudioRole(QStringLiteral("customRole" )); |
1369 | QCOMPARE(player.audioRole(), QAudio::UnknownRole); |
1370 | QVERIFY(player.customAudioRole().isEmpty()); |
1371 | QCOMPARE(spyRole.count(), 0); |
1372 | QCOMPARE(spyCustomRole.count(), 0); |
1373 | } |
1374 | |
1375 | { |
1376 | mockService->reset(); |
1377 | QMediaPlayer player; |
1378 | QSignalSpy spyRole(&player, SIGNAL(audioRoleChanged(QAudio::Role))); |
1379 | QSignalSpy spyCustomRole(&player, SIGNAL(customAudioRoleChanged(const QString &))); |
1380 | |
1381 | QCOMPARE(player.audioRole(), QAudio::UnknownRole); |
1382 | QVERIFY(player.customAudioRole().isEmpty()); |
1383 | QVERIFY(!player.supportedCustomAudioRoles().isEmpty()); |
1384 | |
1385 | QString customRole(QStringLiteral("customRole" )); |
1386 | player.setCustomAudioRole(customRole); |
1387 | QCOMPARE(player.audioRole(), QAudio::CustomRole); |
1388 | QCOMPARE(player.customAudioRole(), customRole); |
1389 | QCOMPARE(mockService->mockAudioRoleControl->audioRole(), QAudio::CustomRole); |
1390 | QCOMPARE(mockService->mockCustomAudioRoleControl->customAudioRole(), customRole); |
1391 | QCOMPARE(spyRole.count(), 1); |
1392 | QCOMPARE(qvariant_cast<QAudio::Role>(spyRole.last().value(0)), QAudio::CustomRole); |
1393 | QCOMPARE(spyCustomRole.count(), 1); |
1394 | QCOMPARE(qvariant_cast<QString>(spyCustomRole.last().value(0)), customRole); |
1395 | |
1396 | spyRole.clear(); |
1397 | spyCustomRole.clear(); |
1398 | |
1399 | QString customRole2(QStringLiteral("customRole2" )); |
1400 | player.setProperty(name: "customAudioRole" , value: QVariant::fromValue(value: customRole2)); |
1401 | QCOMPARE(qvariant_cast<QString>(player.property("customAudioRole" )), customRole2); |
1402 | QCOMPARE(mockService->mockCustomAudioRoleControl->customAudioRole(), customRole2); |
1403 | QCOMPARE(spyRole.count(), 0); |
1404 | QCOMPARE(spyCustomRole.count(), 1); |
1405 | QCOMPARE(qvariant_cast<QString>(spyCustomRole.last().value(0)), customRole2); |
1406 | |
1407 | spyRole.clear(); |
1408 | spyCustomRole.clear(); |
1409 | |
1410 | player.setAudioRole(QAudio::MusicRole); |
1411 | QCOMPARE(player.audioRole(), QAudio::MusicRole); |
1412 | QVERIFY(player.customAudioRole().isEmpty()); |
1413 | QCOMPARE(mockService->mockAudioRoleControl->audioRole(), QAudio::MusicRole); |
1414 | QVERIFY(mockService->mockCustomAudioRoleControl->customAudioRole().isEmpty()); |
1415 | QCOMPARE(spyRole.count(), 1); |
1416 | QCOMPARE(qvariant_cast<QAudio::Role>(spyRole.last().value(0)), QAudio::MusicRole); |
1417 | QCOMPARE(spyCustomRole.count(), 1); |
1418 | QVERIFY(qvariant_cast<QString>(spyCustomRole.last().value(0)).isEmpty()); |
1419 | |
1420 | spyRole.clear(); |
1421 | spyCustomRole.clear(); |
1422 | |
1423 | player.setAudioRole(QAudio::CustomRole); |
1424 | QCOMPARE(player.audioRole(), QAudio::CustomRole); |
1425 | QVERIFY(player.customAudioRole().isEmpty()); |
1426 | QCOMPARE(mockService->mockAudioRoleControl->audioRole(), QAudio::CustomRole); |
1427 | QVERIFY(mockService->mockCustomAudioRoleControl->customAudioRole().isEmpty()); |
1428 | QCOMPARE(spyRole.count(), 1); |
1429 | QCOMPARE(qvariant_cast<QAudio::Role>(spyRole.last().value(0)), QAudio::CustomRole); |
1430 | QCOMPARE(spyCustomRole.count(), 0); |
1431 | } |
1432 | } |
1433 | |
1434 | QTEST_GUILESS_MAIN(tst_QMediaPlayer) |
1435 | #include "tst_qmediaplayer.moc" |
1436 | |