File indexing completed on 2024-04-14 14:17:19
0001 /* 0002 * SPDX-FileCopyrightText: 2019 Manuel Weichselbaumer <mincequi@web.de> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "mediatransporttest.h" 0008 #include "a2dp-codecs.h" 0009 #include "autotests.h" 0010 #include "initmanagerjob.h" 0011 #include "pendingcall.h" 0012 #include "services.h" 0013 0014 #include <QSignalSpy> 0015 #include <QTest> 0016 0017 namespace BluezQt 0018 { 0019 extern void bluezqt_initFakeBluezTestRun(); 0020 } 0021 0022 using namespace BluezQt; 0023 0024 Q_DECLARE_METATYPE(MediaTransport::State) 0025 0026 static a2dp_sbc_t sbcConfiguration; 0027 static a2dp_aac_t aacConfiguration; 0028 0029 static AudioCodec charToCodec(uchar value) 0030 { 0031 switch (value) { 0032 case A2DP_CODEC_SBC: 0033 return AudioCodec::Sbc; 0034 break; 0035 case A2DP_CODEC_MPEG24: 0036 return AudioCodec::Aac; 0037 break; 0038 } 0039 0040 return AudioCodec::Invalid; 0041 } 0042 0043 static AudioSampleRate byteArrayToSampleRate(AudioCodec codec, const QByteArray &buffer) 0044 { 0045 switch (codec) { 0046 case AudioCodec::Sbc: { 0047 if (buffer.size() != sizeof(a2dp_sbc_t)) { 0048 return AudioSampleRate::Invalid; 0049 } 0050 0051 a2dp_sbc_t sbcConfig = *reinterpret_cast<const a2dp_sbc_t *>(buffer.constData()); 0052 switch (sbcConfig.frequency) { 0053 case SBC_SAMPLING_FREQ_44100: 0054 return AudioSampleRate::Rate44100; 0055 break; 0056 case SBC_SAMPLING_FREQ_48000: 0057 return AudioSampleRate::Rate48000; 0058 break; 0059 } 0060 break; 0061 } 0062 case AudioCodec::Aac: { 0063 if (buffer.size() != sizeof(a2dp_aac_t)) { 0064 return AudioSampleRate::Invalid; 0065 } 0066 0067 a2dp_aac_t aacConfig = *reinterpret_cast<const a2dp_aac_t *>(buffer.constData()); 0068 switch (AAC_GET_FREQUENCY(aacConfig)) { 0069 case AAC_SAMPLING_FREQ_44100: 0070 return AudioSampleRate::Rate44100; 0071 break; 0072 case AAC_SAMPLING_FREQ_48000: 0073 return AudioSampleRate::Rate48000; 0074 break; 0075 } 0076 break; 0077 } 0078 } 0079 0080 return AudioSampleRate::Invalid; 0081 } 0082 0083 QString stateString(MediaTransport::State state) 0084 { 0085 switch (state) { 0086 case MediaTransport::State::Idle: 0087 return QStringLiteral("idle"); 0088 case MediaTransport::State::Pending: 0089 return QStringLiteral("pending"); 0090 case MediaTransport::State::Active: 0091 return QStringLiteral("active"); 0092 } 0093 0094 return {}; 0095 } 0096 0097 MediaTransportTest::MediaTransportTest() 0098 : m_manager(nullptr) 0099 { 0100 Autotests::registerMetatypes(); 0101 0102 qRegisterMetaType<MediaTransport::State>("State"); 0103 0104 sbcConfiguration.frequency = SBC_SAMPLING_FREQ_44100; 0105 AAC_SET_FREQUENCY(aacConfiguration, AAC_SAMPLING_FREQ_48000); 0106 } 0107 0108 void MediaTransportTest::initTestCase() 0109 { 0110 bluezqt_initFakeBluezTestRun(); 0111 0112 FakeBluez::start(); 0113 FakeBluez::runTest(QStringLiteral("bluez-standard")); 0114 0115 // Create adapter 0116 QString adapter = QStringLiteral("/org/bluez/hci0"); 0117 QVariantMap adapterProps; 0118 adapterProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath(adapter)); 0119 adapterProps[QStringLiteral("Address")] = QStringLiteral("1C:E5:C3:BC:94:7E"); 0120 adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter"); 0121 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps); 0122 0123 // Create devices 0124 QVariantMap deviceProps; 0125 QVariantMap mediaTransportProps; 0126 0127 QString device1 = adapter + QLatin1String("/dev_40_79_6A_0C_39_75"); 0128 deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath(device1)); 0129 deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(QDBusObjectPath(adapter)); 0130 deviceProps[QStringLiteral("Address")] = QStringLiteral("40:79:6A:0C:39:75"); 0131 deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice"); 0132 deviceProps[QStringLiteral("UUIDs")] = QStringList(Services::AudioSink); 0133 mediaTransportProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath(device1 + QLatin1String("/fd0"))); 0134 mediaTransportProps[QStringLiteral("Device")] = QVariant::fromValue(QDBusObjectPath(device1)); 0135 mediaTransportProps[QStringLiteral("UUID")] = Services::AudioSink; 0136 mediaTransportProps[QStringLiteral("Codec")] = QVariant::fromValue(quint8(A2DP_CODEC_SBC)); // SBC 0137 mediaTransportProps[QStringLiteral("Configuration")] = 0138 QVariant::fromValue(QByteArray(reinterpret_cast<const char *>(&sbcConfiguration), sizeof(sbcConfiguration))); 0139 mediaTransportProps[QStringLiteral("State")] = QStringLiteral("pending"); 0140 mediaTransportProps[QStringLiteral("Volume")] = QVariant::fromValue(quint16(63)); 0141 deviceProps[QStringLiteral("MediaTransport")] = mediaTransportProps; 0142 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps); 0143 0144 QString device2 = adapter + QLatin1String("/dev_50_79_6A_0C_39_75"); 0145 deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath(device2)); 0146 deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(QDBusObjectPath(adapter)); 0147 deviceProps[QStringLiteral("Address")] = QStringLiteral("50:79:6A:0C:39:75"); 0148 deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice2"); 0149 deviceProps[QStringLiteral("UUIDs")] = QStringList(Services::AudioSink); 0150 mediaTransportProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath(device2 + QLatin1String("/fd0"))); 0151 mediaTransportProps[QStringLiteral("Device")] = QVariant::fromValue(QDBusObjectPath(device2)); 0152 mediaTransportProps[QStringLiteral("UUID")] = Services::AudioSink; 0153 mediaTransportProps[QStringLiteral("Codec")] = QVariant::fromValue(quint8(A2DP_CODEC_MPEG24)); // AAC 0154 mediaTransportProps[QStringLiteral("Configuration")] = 0155 QVariant::fromValue(QByteArray(reinterpret_cast<const char *>(&aacConfiguration), sizeof(aacConfiguration))); 0156 mediaTransportProps[QStringLiteral("State")] = QStringLiteral("active"); 0157 mediaTransportProps[QStringLiteral("Volume")] = QVariant::fromValue(quint16(127)); 0158 deviceProps[QStringLiteral("MediaTransport")] = mediaTransportProps; 0159 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps); 0160 0161 m_manager = new Manager(); 0162 InitManagerJob *initJob = m_manager->init(); 0163 initJob->exec(); 0164 QVERIFY(!initJob->error()); 0165 0166 QCOMPARE(m_manager->adapters().count(), 1); 0167 QCOMPARE(m_manager->devices().count(), 2); 0168 } 0169 0170 void MediaTransportTest::cleanupTestCase() 0171 { 0172 for (const MediaTransportUnit &unit : m_units) { 0173 delete unit.dbusMediaTransport; 0174 delete unit.dbusProperties; 0175 } 0176 0177 delete m_manager; 0178 0179 FakeBluez::stop(); 0180 } 0181 0182 void MediaTransportTest::connectTest() 0183 { 0184 for (DevicePtr device : m_manager->devices()) { 0185 QVERIFY(!device->ubi().isEmpty()); 0186 QVERIFY(!device->mediaTransport()); 0187 0188 QSignalSpy deviceSpy(device.data(), SIGNAL(mediaTransportChanged(MediaTransportPtr))); 0189 0190 device->connectToDevice(); 0191 QTRY_COMPARE(deviceSpy.count(), 1); 0192 QVERIFY(device->mediaTransport()); 0193 } 0194 } 0195 0196 void MediaTransportTest::disconnectTest() 0197 { 0198 for (DevicePtr device : m_manager->devices()) { 0199 QVERIFY(device->mediaTransport()); 0200 0201 QSignalSpy deviceSpy(device.data(), SIGNAL(mediaTransportChanged(MediaTransportPtr))); 0202 0203 device->disconnectFromDevice(); 0204 QTRY_COMPARE(deviceSpy.count(), 1); 0205 QVERIFY(!device->mediaTransport()); 0206 } 0207 } 0208 0209 void MediaTransportTest::connectProfileTest() 0210 { 0211 QDBusConnection connection = QDBusConnection::sessionBus(); 0212 QString service = QStringLiteral("org.kde.bluezqt.fakebluez"); 0213 0214 for (DevicePtr device : m_manager->devices()) { 0215 QVERIFY(!device->ubi().isEmpty()); 0216 QVERIFY(!device->mediaTransport()); 0217 0218 QSignalSpy deviceSpy(device.data(), SIGNAL(mediaTransportChanged(MediaTransportPtr))); 0219 0220 device->connectProfile(Services::AudioSink); 0221 QTRY_COMPARE(deviceSpy.count(), 1); 0222 QVERIFY(device->mediaTransport()); 0223 0224 QString path = device->ubi() + QLatin1String("/fd0"); 0225 0226 MediaTransportUnit unit; 0227 unit.device = device; 0228 unit.dbusMediaTransport = new org::bluez::MediaTransport1(service, path, connection, this); 0229 unit.dbusProperties = new org::freedesktop::DBus::Properties(service, path, connection, this); 0230 m_units.append(unit); 0231 } 0232 } 0233 0234 void MediaTransportTest::getPropertiesTest() 0235 { 0236 for (const MediaTransportUnit &unit : m_units) { 0237 QCOMPARE(unit.device->mediaTransport()->audioConfiguration().codec, charToCodec(unit.dbusMediaTransport->codec())); 0238 QCOMPARE(unit.device->mediaTransport()->audioConfiguration().sampleRate, 0239 byteArrayToSampleRate(unit.device->mediaTransport()->audioConfiguration().codec, unit.dbusMediaTransport->configuration())); 0240 QCOMPARE(stateString(unit.device->mediaTransport()->state()), unit.dbusMediaTransport->state()); 0241 QCOMPARE(unit.device->mediaTransport()->volume(), unit.dbusMediaTransport->volume()); 0242 } 0243 } 0244 0245 void MediaTransportTest::disconnectProfileTest() 0246 { 0247 for (const MediaTransportUnit &unit : m_units) { 0248 QVERIFY(unit.device->mediaTransport()); 0249 0250 QSignalSpy deviceSpy(unit.device.data(), SIGNAL(mediaTransportChanged(MediaTransportPtr))); 0251 0252 unit.device->disconnectProfile(Services::AudioSink); 0253 QTRY_COMPARE(deviceSpy.count(), 1); 0254 QVERIFY(!unit.device->mediaTransport()); 0255 } 0256 } 0257 0258 QTEST_MAIN(MediaTransportTest) 0259 0260 #include "moc_mediatransporttest.cpp"