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/qtimer.h>
34
35#include <QtMultimedia/qmediametadata.h>
36#include <qmediaobject.h>
37#include <qmediaservice.h>
38#include <qmetadatareadercontrol.h>
39#include <qaudioinputselectorcontrol.h>
40
41#include "mockmediarecorderservice.h"
42#include "mockmediaserviceprovider.h"
43#include "mockmetadatareadercontrol.h"
44#include "mockavailabilitycontrol.h"
45
46class QtTestMediaObjectService : public QMediaService
47{
48 Q_OBJECT
49public:
50 QtTestMediaObjectService(QObject *parent = 0, MockAvailabilityControl *availability = 0)
51 : QMediaService(parent)
52 , availabilityControl(availability)
53 , metaDataRef(0)
54 , hasMetaData(true)
55 {
56 }
57
58 QMediaControl *requestControl(const char *iid)
59 {
60 if (hasMetaData && qstrcmp(str1: iid, QMetaDataReaderControl_iid) == 0)
61 return &metaData;
62 else if (qstrcmp(str1: iid, QMediaAvailabilityControl_iid) == 0)
63 return availabilityControl;
64 else
65 return 0;
66 }
67
68 void releaseControl(QMediaControl *)
69 {
70 }
71
72 MockMetaDataReaderControl metaData;
73 MockAvailabilityControl *availabilityControl;
74 int metaDataRef;
75 bool hasMetaData;
76};
77
78QT_USE_NAMESPACE
79
80class tst_QMediaObject : public QObject
81{
82 Q_OBJECT
83
84private slots:
85 void propertyWatch();
86 void notifySignals_data();
87 void notifySignals();
88 void notifyInterval_data();
89 void notifyInterval();
90
91 void nullMetaDataControl();
92 void isMetaDataAvailable();
93 void metaDataChanged();
94 void metaData_data();
95 void metaData();
96 void availability();
97
98 void service();
99
100private:
101 void setupNotifyTests();
102};
103
104class QtTestMediaObject : public QMediaObject
105{
106 Q_OBJECT
107 Q_PROPERTY(int a READ a WRITE setA NOTIFY aChanged)
108 Q_PROPERTY(int b READ b WRITE setB NOTIFY bChanged)
109 Q_PROPERTY(int c READ c WRITE setC NOTIFY cChanged)
110 Q_PROPERTY(int d READ d WRITE setD)
111public:
112 QtTestMediaObject(QMediaService *service = 0): QMediaObject(0, service), m_a(0), m_b(0), m_c(0), m_d(0) {}
113
114 using QMediaObject::addPropertyWatch;
115 using QMediaObject::removePropertyWatch;
116
117 int a() const { return m_a; }
118 void setA(int a) { m_a = a; }
119
120 int b() const { return m_b; }
121 void setB(int b) { m_b = b; }
122
123 int c() const { return m_c; }
124 void setC(int c) { m_c = c; }
125
126 int d() const { return m_d; }
127 void setD(int d) { m_d = d; }
128
129Q_SIGNALS:
130 void aChanged(int a);
131 void bChanged(int b);
132 void cChanged(int c);
133
134private:
135 int m_a;
136 int m_b;
137 int m_c;
138 int m_d;
139};
140
141void tst_QMediaObject::propertyWatch()
142{
143 QtTestMediaObject object;
144 object.setNotifyInterval(0);
145
146 QEventLoop loop;
147 connect(sender: &object, SIGNAL(aChanged(int)), receiver: &QTestEventLoop::instance(), SLOT(exitLoop()));
148 connect(sender: &object, SIGNAL(bChanged(int)), receiver: &QTestEventLoop::instance(), SLOT(exitLoop()));
149 connect(sender: &object, SIGNAL(cChanged(int)), receiver: &QTestEventLoop::instance(), SLOT(exitLoop()));
150
151 QSignalSpy aSpy(&object, SIGNAL(aChanged(int)));
152 QSignalSpy bSpy(&object, SIGNAL(bChanged(int)));
153 QSignalSpy cSpy(&object, SIGNAL(cChanged(int)));
154
155 QTestEventLoop::instance().enterLoop(secs: 1);
156
157 QCOMPARE(aSpy.count(), 0);
158 QCOMPARE(bSpy.count(), 0);
159 QCOMPARE(cSpy.count(), 0);
160
161 int aCount = 0;
162 int bCount = 0;
163 int cCount = 0;
164
165 object.addPropertyWatch(name: "a");
166
167 QTestEventLoop::instance().enterLoop(secs: 1);
168
169 QVERIFY(aSpy.count() > aCount);
170 QCOMPARE(bSpy.count(), 0);
171 QCOMPARE(cSpy.count(), 0);
172 QCOMPARE(aSpy.last().value(0).toInt(), 0);
173
174 aCount = aSpy.count();
175
176 object.setA(54);
177 object.setB(342);
178 object.setC(233);
179
180 QTestEventLoop::instance().enterLoop(secs: 1);
181
182 QVERIFY(aSpy.count() > aCount);
183 QCOMPARE(bSpy.count(), 0);
184 QCOMPARE(cSpy.count(), 0);
185 QCOMPARE(aSpy.last().value(0).toInt(), 54);
186
187 aCount = aSpy.count();
188
189 object.addPropertyWatch(name: "b");
190 object.addPropertyWatch(name: "d");
191 object.removePropertyWatch(name: "e");
192 object.setA(43);
193 object.setB(235);
194 object.setC(90);
195
196 QTestEventLoop::instance().enterLoop(secs: 1);
197
198 QVERIFY(aSpy.count() > aCount);
199 QVERIFY(bSpy.count() > bCount);
200 QCOMPARE(cSpy.count(), 0);
201 QCOMPARE(aSpy.last().value(0).toInt(), 43);
202 QCOMPARE(bSpy.last().value(0).toInt(), 235);
203
204 aCount = aSpy.count();
205 bCount = bSpy.count();
206
207 object.removePropertyWatch(name: "a");
208 object.addPropertyWatch(name: "c");
209 object.addPropertyWatch(name: "e");
210
211 QTestEventLoop::instance().enterLoop(secs: 1);
212
213 QCOMPARE(aSpy.count(), aCount);
214 QVERIFY(bSpy.count() > bCount);
215 QVERIFY(cSpy.count() > cCount);
216 QCOMPARE(bSpy.last().value(0).toInt(), 235);
217 QCOMPARE(cSpy.last().value(0).toInt(), 90);
218
219 bCount = bSpy.count();
220 cCount = cSpy.count();
221
222 object.setA(435);
223 object.setC(9845);
224
225 QTestEventLoop::instance().enterLoop(secs: 1);
226
227 QCOMPARE(aSpy.count(), aCount);
228 QVERIFY(bSpy.count() > bCount);
229 QVERIFY(cSpy.count() > cCount);
230 QCOMPARE(bSpy.last().value(0).toInt(), 235);
231 QCOMPARE(cSpy.last().value(0).toInt(), 9845);
232
233 bCount = bSpy.count();
234 cCount = cSpy.count();
235
236 object.setA(8432);
237 object.setB(324);
238 object.setC(443);
239 object.removePropertyWatch(name: "c");
240 object.removePropertyWatch(name: "d");
241
242 QTestEventLoop::instance().enterLoop(secs: 1);
243
244 QCOMPARE(aSpy.count(), aCount);
245 QVERIFY(bSpy.count() > bCount);
246 QCOMPARE(cSpy.count(), cCount);
247 QCOMPARE(bSpy.last().value(0).toInt(), 324);
248 QCOMPARE(cSpy.last().value(0).toInt(), 9845);
249
250 bCount = bSpy.count();
251
252 object.removePropertyWatch(name: "b");
253
254 QTestEventLoop::instance().enterLoop(secs: 1);
255
256 QCOMPARE(aSpy.count(), aCount);
257 QCOMPARE(bSpy.count(), bCount);
258 QCOMPARE(cSpy.count(), cCount);
259}
260
261void tst_QMediaObject::setupNotifyTests()
262{
263 QTest::addColumn<int>(name: "interval");
264 QTest::addColumn<int>(name: "count");
265
266 QTest::newRow(dataTag: "single 750ms")
267 << 750
268 << 1;
269 QTest::newRow(dataTag: "single 600ms")
270 << 600
271 << 1;
272 QTest::newRow(dataTag: "x3 300ms")
273 << 300
274 << 3;
275 QTest::newRow(dataTag: "x5 180ms")
276 << 180
277 << 5;
278}
279
280void tst_QMediaObject::notifySignals_data()
281{
282 setupNotifyTests();
283}
284
285void tst_QMediaObject::notifySignals()
286{
287 QFETCH(int, interval);
288 QFETCH(int, count);
289
290 QtTestMediaObject object;
291 QSignalSpy spy(&object, SIGNAL(aChanged(int)));
292
293 object.setNotifyInterval(interval);
294 object.addPropertyWatch(name: "a");
295
296 QElapsedTimer timer;
297 timer.start();
298
299 QTRY_COMPARE(spy.count(), count);
300}
301
302void tst_QMediaObject::notifyInterval_data()
303{
304 setupNotifyTests();
305}
306
307void tst_QMediaObject::notifyInterval()
308{
309 QFETCH(int, interval);
310
311 QtTestMediaObject object;
312 QSignalSpy spy(&object, SIGNAL(notifyIntervalChanged(int)));
313
314 object.setNotifyInterval(interval);
315 QCOMPARE(object.notifyInterval(), interval);
316 QCOMPARE(spy.count(), 1);
317 QCOMPARE(spy.last().value(0).toInt(), interval);
318
319 object.setNotifyInterval(interval);
320 QCOMPARE(object.notifyInterval(), interval);
321 QCOMPARE(spy.count(), 1);
322}
323
324void tst_QMediaObject::nullMetaDataControl()
325{
326 const QString titleKey(QLatin1String("Title"));
327 const QString title(QLatin1String("Host of Seraphim"));
328
329 QtTestMediaObjectService service;
330 service.hasMetaData = false;
331
332 QtTestMediaObject object(&service);
333
334 QSignalSpy spy(&object, SIGNAL(metaDataChanged()));
335
336 QCOMPARE(object.isMetaDataAvailable(), false);
337
338 QCOMPARE(object.metaData(QMediaMetaData::Title).toString(), QString());
339 QCOMPARE(object.availableMetaData(), QStringList());
340 QCOMPARE(spy.count(), 0);
341}
342
343void tst_QMediaObject::isMetaDataAvailable()
344{
345 QtTestMediaObjectService service;
346 service.metaData.setMetaDataAvailable(false);
347
348 QtTestMediaObject object(&service);
349 QCOMPARE(object.isMetaDataAvailable(), false);
350
351 QSignalSpy spy(&object, SIGNAL(metaDataAvailableChanged(bool)));
352 service.metaData.setMetaDataAvailable(true);
353
354 QCOMPARE(object.isMetaDataAvailable(), true);
355 QCOMPARE(spy.count(), 1);
356 QCOMPARE(spy.at(0).at(0).toBool(), true);
357
358 service.metaData.setMetaDataAvailable(false);
359
360 QCOMPARE(object.isMetaDataAvailable(), false);
361 QCOMPARE(spy.count(), 2);
362 QCOMPARE(spy.at(1).at(0).toBool(), false);
363}
364
365void tst_QMediaObject::metaDataChanged()
366{
367 QtTestMediaObjectService service;
368 QtTestMediaObject object(&service);
369
370 QSignalSpy changedSpy(&object, SIGNAL(metaDataChanged()));
371 QSignalSpy changedWithValueSpy(&object, SIGNAL(metaDataChanged(QString,QVariant)));
372
373 service.metaData.setMetaData(key: "key", value: "Value");
374 QCOMPARE(changedSpy.count(), 1);
375 QCOMPARE(changedWithValueSpy.count(), 1);
376 QCOMPARE(changedWithValueSpy.last()[0], QVariant("key"));
377 QCOMPARE(changedWithValueSpy.last()[1].value<QVariant>(), QVariant("Value"));
378
379 service.metaData.setMetaData(key: "key", value: "Value");
380 QCOMPARE(changedSpy.count(), 1);
381 QCOMPARE(changedWithValueSpy.count(), 1);
382
383 service.metaData.setMetaData(key: "key2", value: "Value");
384 QCOMPARE(changedSpy.count(), 2);
385 QCOMPARE(changedWithValueSpy.count(), 2);
386 QCOMPARE(changedWithValueSpy.last()[0], QVariant("key2"));
387 QCOMPARE(changedWithValueSpy.last()[1].value<QVariant>(), QVariant("Value"));
388}
389
390void tst_QMediaObject::metaData_data()
391{
392 QTest::addColumn<QString>(name: "artist");
393 QTest::addColumn<QString>(name: "title");
394 QTest::addColumn<QString>(name: "genre");
395
396 QTest::newRow(dataTag: "")
397 << QString::fromLatin1(str: "Dead Can Dance")
398 << QString::fromLatin1(str: "Host of Seraphim")
399 << QString::fromLatin1(str: "Awesome");
400}
401
402void tst_QMediaObject::metaData()
403{
404 QFETCH(QString, artist);
405 QFETCH(QString, title);
406 QFETCH(QString, genre);
407
408 QtTestMediaObjectService service;
409 service.metaData.populateMetaData();
410
411 QtTestMediaObject object(&service);
412 QVERIFY(object.availableMetaData().isEmpty());
413
414 service.metaData.m_data.insert(key: QMediaMetaData::AlbumArtist, value: artist);
415 service.metaData.m_data.insert(key: QMediaMetaData::Title, value: title);
416 service.metaData.m_data.insert(key: QMediaMetaData::Genre, value: genre);
417
418 QCOMPARE(object.metaData(QMediaMetaData::AlbumArtist).toString(), artist);
419 QCOMPARE(object.metaData(QMediaMetaData::Title).toString(), title);
420
421 QStringList metaDataKeys = object.availableMetaData();
422 QCOMPARE(metaDataKeys.size(), 3);
423 QVERIFY(metaDataKeys.contains(QMediaMetaData::AlbumArtist));
424 QVERIFY(metaDataKeys.contains(QMediaMetaData::Title));
425 QVERIFY(metaDataKeys.contains(QMediaMetaData::Genre));
426}
427
428void tst_QMediaObject::availability()
429{
430 {
431 QtTestMediaObject nullObject(0);
432 QCOMPARE(nullObject.isAvailable(), false);
433 QCOMPARE(nullObject.availability(), QMultimedia::ServiceMissing);
434 }
435
436 {
437 QtTestMediaObjectService service;
438 QtTestMediaObject object(&service);
439 QCOMPARE(object.isAvailable(), true);
440 QCOMPARE(object.availability(), QMultimedia::Available);
441 }
442
443 {
444 MockAvailabilityControl available(QMultimedia::Available);
445 QtTestMediaObjectService service(0, &available);
446 QtTestMediaObject object(&service);
447 QSignalSpy availabilitySpy(&object, SIGNAL(availabilityChanged(bool)));
448 QSignalSpy availabilityStatusSpy(&object, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)));
449
450 QCOMPARE(object.isAvailable(), true);
451 QCOMPARE(object.availability(), QMultimedia::Available);
452
453 available.setAvailability(QMultimedia::Busy);
454 QCOMPARE(object.isAvailable(), false);
455 QCOMPARE(object.availability(), QMultimedia::Busy);
456 QCOMPARE(availabilitySpy.count(), 1);
457 QCOMPARE(availabilityStatusSpy.count(), 1);
458
459 available.setAvailability(QMultimedia::Available);
460 QCOMPARE(object.isAvailable(), true);
461 QCOMPARE(object.availability(), QMultimedia::Available);
462 QCOMPARE(availabilitySpy.count(), 2);
463 QCOMPARE(availabilityStatusSpy.count(), 2);
464 }
465
466 {
467 MockAvailabilityControl available(QMultimedia::Busy);
468 QtTestMediaObjectService service(0, &available);
469 QtTestMediaObject object(&service);
470 QSignalSpy availabilitySpy(&object, SIGNAL(availabilityChanged(bool)));
471 QSignalSpy availabilityStatusSpy(&object, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)));
472
473 QCOMPARE(object.isAvailable(), false);
474 QCOMPARE(object.availability(), QMultimedia::Busy);
475
476 available.setAvailability(QMultimedia::Available);
477 QCOMPARE(object.isAvailable(), true);
478 QCOMPARE(object.availability(), QMultimedia::Available);
479 QCOMPARE(availabilitySpy.count(), 1);
480 QCOMPARE(availabilityStatusSpy.count(), 1);
481 }
482}
483
484 void tst_QMediaObject::service()
485 {
486 // Create the mediaobject with service.
487 QtTestMediaObjectService service;
488 QtTestMediaObject mediaObject1(&service);
489
490 // Get service and Compare if it equal to the service passed as an argument in mediaObject1.
491 QMediaService *service1 = mediaObject1.service();
492 QVERIFY(service1 != NULL);
493 QCOMPARE(service1,&service);
494
495 // Create the mediaobject with empty service and verify that service() returns NULL.
496 QtTestMediaObject mediaObject2;
497 QMediaService *service2 = mediaObject2.service();
498 QVERIFY(service2 == NULL);
499}
500
501QTEST_GUILESS_MAIN(tst_QMediaObject)
502#include "tst_qmediaobject.moc"
503

source code of qtmultimedia/tests/auto/unit/qmediaobject/tst_qmediaobject.cpp