2020-03-15 15:19:28 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
|
2014-11-04 14:10:22 +00:00
|
|
|
|
2020-03-15 15:19:28 +00:00
|
|
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
|
|
*/
|
2014-11-04 14:10:22 +00:00
|
|
|
// Qt
|
2018-11-06 06:22:36 +00:00
|
|
|
#include <QtTest>
|
2014-11-04 14:10:22 +00:00
|
|
|
#include <QMimeDatabase>
|
|
|
|
// KWayland
|
2020-04-29 13:59:23 +00:00
|
|
|
#include "KWayland/Client/connection_thread.h"
|
|
|
|
#include "KWayland/Client/event_queue.h"
|
|
|
|
#include "KWayland/Client/datadevicemanager.h"
|
|
|
|
#include "KWayland/Client/datasource.h"
|
|
|
|
#include "KWayland/Client/registry.h"
|
2014-11-04 14:10:22 +00:00
|
|
|
#include "../../src/server/display.h"
|
|
|
|
#include "../../src/server/datadevicemanager_interface.h"
|
|
|
|
#include "../../src/server/datasource_interface.h"
|
|
|
|
// Wayland
|
|
|
|
#include <wayland-client.h>
|
|
|
|
|
|
|
|
class TestDataSource : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
private Q_SLOTS:
|
|
|
|
void init();
|
|
|
|
void cleanup();
|
|
|
|
|
|
|
|
void testOffer();
|
|
|
|
void testTargetAccepts_data();
|
|
|
|
void testTargetAccepts();
|
|
|
|
void testRequestSend();
|
|
|
|
void testCancel();
|
2014-11-05 14:22:15 +00:00
|
|
|
void testServerGet();
|
2014-11-04 14:10:22 +00:00
|
|
|
void testDestroy();
|
|
|
|
|
|
|
|
private:
|
2020-04-29 14:56:38 +00:00
|
|
|
KWaylandServer::Display *m_display = nullptr;
|
|
|
|
KWaylandServer::DataDeviceManagerInterface *m_dataDeviceManagerInterface = nullptr;
|
2014-11-04 14:10:22 +00:00
|
|
|
KWayland::Client::ConnectionThread *m_connection = nullptr;
|
|
|
|
KWayland::Client::DataDeviceManager *m_dataDeviceManager = nullptr;
|
|
|
|
KWayland::Client::EventQueue *m_queue = nullptr;
|
|
|
|
QThread *m_thread = nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const QString s_socketName = QStringLiteral("kwayland-test-wayland-datasource-0");
|
|
|
|
|
|
|
|
void TestDataSource::init()
|
|
|
|
{
|
2020-04-29 14:56:38 +00:00
|
|
|
using namespace KWaylandServer;
|
2014-11-04 14:10:22 +00:00
|
|
|
delete m_display;
|
|
|
|
m_display = new Display(this);
|
2020-10-19 15:52:56 +00:00
|
|
|
m_display->addSocketName(s_socketName);
|
2014-11-04 14:10:22 +00:00
|
|
|
m_display->start();
|
|
|
|
QVERIFY(m_display->isRunning());
|
|
|
|
|
|
|
|
// setup connection
|
|
|
|
m_connection = new KWayland::Client::ConnectionThread;
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
|
2014-11-04 14:10:22 +00:00
|
|
|
m_connection->setSocketName(s_socketName);
|
|
|
|
|
|
|
|
m_thread = new QThread(this);
|
|
|
|
m_connection->moveToThread(m_thread);
|
|
|
|
m_thread->start();
|
|
|
|
|
|
|
|
m_connection->initConnection();
|
|
|
|
QVERIFY(connectedSpy.wait());
|
|
|
|
|
|
|
|
m_queue = new KWayland::Client::EventQueue(this);
|
|
|
|
QVERIFY(!m_queue->isValid());
|
|
|
|
m_queue->setup(m_connection);
|
|
|
|
QVERIFY(m_queue->isValid());
|
|
|
|
|
|
|
|
KWayland::Client::Registry registry;
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy dataDeviceManagerSpy(®istry, &KWayland::Client::Registry::dataDeviceManagerAnnounced);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(dataDeviceManagerSpy.isValid());
|
|
|
|
QVERIFY(!registry.eventQueue());
|
|
|
|
registry.setEventQueue(m_queue);
|
|
|
|
QCOMPARE(registry.eventQueue(), m_queue);
|
|
|
|
registry.create(m_connection->display());
|
|
|
|
QVERIFY(registry.isValid());
|
|
|
|
registry.setup();
|
|
|
|
|
2020-12-09 20:13:19 +00:00
|
|
|
m_dataDeviceManagerInterface = new DataDeviceManagerInterface(m_display, m_display);
|
2014-11-04 14:10:22 +00:00
|
|
|
|
|
|
|
QVERIFY(dataDeviceManagerSpy.wait());
|
|
|
|
m_dataDeviceManager = registry.createDataDeviceManager(dataDeviceManagerSpy.first().first().value<quint32>(),
|
|
|
|
dataDeviceManagerSpy.first().last().value<quint32>(), this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestDataSource::cleanup()
|
|
|
|
{
|
|
|
|
if (m_dataDeviceManager) {
|
|
|
|
delete m_dataDeviceManager;
|
|
|
|
m_dataDeviceManager = nullptr;
|
|
|
|
}
|
|
|
|
if (m_queue) {
|
|
|
|
delete m_queue;
|
|
|
|
m_queue = nullptr;
|
|
|
|
}
|
|
|
|
if (m_thread) {
|
|
|
|
m_thread->quit();
|
|
|
|
m_thread->wait();
|
|
|
|
delete m_thread;
|
|
|
|
m_thread = nullptr;
|
|
|
|
}
|
|
|
|
delete m_connection;
|
|
|
|
m_connection = nullptr;
|
|
|
|
|
|
|
|
delete m_display;
|
|
|
|
m_display = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestDataSource::testOffer()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
2020-04-29 14:56:38 +00:00
|
|
|
using namespace KWaylandServer;
|
2014-11-04 14:10:22 +00:00
|
|
|
|
2020-04-29 14:56:38 +00:00
|
|
|
qRegisterMetaType<KWaylandServer::DataSourceInterface*>();
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWaylandServer::DataDeviceManagerInterface::dataSourceCreated);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(dataSourceCreatedSpy.isValid());
|
|
|
|
|
|
|
|
QScopedPointer<DataSource> dataSource(m_dataDeviceManager->createDataSource());
|
|
|
|
QVERIFY(dataSource->isValid());
|
|
|
|
|
|
|
|
QVERIFY(dataSourceCreatedSpy.wait());
|
|
|
|
QCOMPARE(dataSourceCreatedSpy.count(), 1);
|
|
|
|
|
|
|
|
QPointer<DataSourceInterface> serverDataSource = dataSourceCreatedSpy.first().first().value<DataSourceInterface*>();
|
|
|
|
QVERIFY(!serverDataSource.isNull());
|
|
|
|
QCOMPARE(serverDataSource->mimeTypes().count(), 0);
|
|
|
|
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy offeredSpy(serverDataSource.data(), &KWaylandServer::AbstractDataSource::mimeTypeOffered);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(offeredSpy.isValid());
|
|
|
|
|
|
|
|
const QString plain = QStringLiteral("text/plain");
|
|
|
|
QMimeDatabase db;
|
|
|
|
dataSource->offer(db.mimeTypeForName(plain));
|
|
|
|
|
|
|
|
QVERIFY(offeredSpy.wait());
|
|
|
|
QCOMPARE(offeredSpy.count(), 1);
|
|
|
|
QCOMPARE(offeredSpy.last().first().toString(), plain);
|
|
|
|
QCOMPARE(serverDataSource->mimeTypes().count(), 1);
|
|
|
|
QCOMPARE(serverDataSource->mimeTypes().first(), plain);
|
|
|
|
|
|
|
|
const QString html = QStringLiteral("text/html");
|
|
|
|
dataSource->offer(db.mimeTypeForName(html));
|
|
|
|
|
|
|
|
QVERIFY(offeredSpy.wait());
|
|
|
|
QCOMPARE(offeredSpy.count(), 2);
|
|
|
|
QCOMPARE(offeredSpy.first().first().toString(), plain);
|
|
|
|
QCOMPARE(offeredSpy.last().first().toString(), html);
|
|
|
|
QCOMPARE(serverDataSource->mimeTypes().count(), 2);
|
|
|
|
QCOMPARE(serverDataSource->mimeTypes().first(), plain);
|
|
|
|
QCOMPARE(serverDataSource->mimeTypes().last(), html);
|
|
|
|
|
|
|
|
// try destroying the client side, should trigger a destroy of server side
|
|
|
|
dataSource.reset();
|
|
|
|
QVERIFY(!serverDataSource.isNull());
|
|
|
|
wl_display_flush(m_connection->display());
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QVERIFY(serverDataSource.isNull());
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestDataSource::testTargetAccepts_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<QString>("mimeType");
|
|
|
|
|
|
|
|
QTest::newRow("empty") << QString();
|
|
|
|
QTest::newRow("text/plain") << QStringLiteral("text/plain");
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestDataSource::testTargetAccepts()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
2020-04-29 14:56:38 +00:00
|
|
|
using namespace KWaylandServer;
|
2014-11-04 14:10:22 +00:00
|
|
|
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWaylandServer::DataDeviceManagerInterface::dataSourceCreated);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(dataSourceCreatedSpy.isValid());
|
|
|
|
|
|
|
|
QScopedPointer<DataSource> dataSource(m_dataDeviceManager->createDataSource());
|
|
|
|
QVERIFY(dataSource->isValid());
|
|
|
|
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy targetAcceptsSpy(dataSource.data(), &KWayland::Client::DataSource::targetAccepts);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(targetAcceptsSpy.isValid());
|
|
|
|
|
|
|
|
QVERIFY(dataSourceCreatedSpy.wait());
|
|
|
|
QCOMPARE(dataSourceCreatedSpy.count(), 1);
|
|
|
|
|
|
|
|
QFETCH(QString, mimeType);
|
|
|
|
dataSourceCreatedSpy.first().first().value<DataSourceInterface*>()->accept(mimeType);
|
|
|
|
|
|
|
|
QVERIFY(targetAcceptsSpy.wait());
|
|
|
|
QCOMPARE(targetAcceptsSpy.count(), 1);
|
|
|
|
QCOMPARE(targetAcceptsSpy.first().first().toString(), mimeType);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestDataSource::testRequestSend()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
2020-04-29 14:56:38 +00:00
|
|
|
using namespace KWaylandServer;
|
2014-11-04 14:10:22 +00:00
|
|
|
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWaylandServer::DataDeviceManagerInterface::dataSourceCreated);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(dataSourceCreatedSpy.isValid());
|
|
|
|
|
|
|
|
QScopedPointer<DataSource> dataSource(m_dataDeviceManager->createDataSource());
|
|
|
|
QVERIFY(dataSource->isValid());
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy sendRequestedSpy(dataSource.data(), &KWayland::Client::DataSource::sendDataRequested);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(sendRequestedSpy.isValid());
|
|
|
|
|
|
|
|
const QString plain = QStringLiteral("text/plain");
|
|
|
|
QVERIFY(dataSourceCreatedSpy.wait());
|
|
|
|
QCOMPARE(dataSourceCreatedSpy.count(), 1);
|
|
|
|
QTemporaryFile file;
|
|
|
|
QVERIFY(file.open());
|
|
|
|
dataSourceCreatedSpy.first().first().value<DataSourceInterface*>()->requestData(plain, file.handle());
|
|
|
|
|
|
|
|
QVERIFY(sendRequestedSpy.wait());
|
|
|
|
QCOMPARE(sendRequestedSpy.count(), 1);
|
|
|
|
QCOMPARE(sendRequestedSpy.first().first().toString(), plain);
|
2014-11-27 12:38:24 +00:00
|
|
|
QCOMPARE(sendRequestedSpy.first().last().value<qint32>(), file.handle());
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(sendRequestedSpy.first().last().value<qint32>() != -1);
|
|
|
|
|
|
|
|
QFile writeFile;
|
|
|
|
QVERIFY(writeFile.open(sendRequestedSpy.first().last().value<qint32>(), QFile::WriteOnly, QFileDevice::AutoCloseHandle));
|
|
|
|
writeFile.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestDataSource::testCancel()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
2020-04-29 14:56:38 +00:00
|
|
|
using namespace KWaylandServer;
|
2014-11-04 14:10:22 +00:00
|
|
|
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWaylandServer::DataDeviceManagerInterface::dataSourceCreated);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(dataSourceCreatedSpy.isValid());
|
|
|
|
|
|
|
|
QScopedPointer<DataSource> dataSource(m_dataDeviceManager->createDataSource());
|
|
|
|
QVERIFY(dataSource->isValid());
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy cancelledSpy(dataSource.data(), &KWayland::Client::DataSource::cancelled);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(cancelledSpy.isValid());
|
|
|
|
|
|
|
|
QVERIFY(dataSourceCreatedSpy.wait());
|
|
|
|
|
|
|
|
QCOMPARE(cancelledSpy.count(), 0);
|
|
|
|
dataSourceCreatedSpy.first().first().value<DataSourceInterface*>()->cancel();
|
|
|
|
|
|
|
|
QVERIFY(cancelledSpy.wait());
|
|
|
|
QCOMPARE(cancelledSpy.count(), 1);
|
|
|
|
}
|
|
|
|
|
2014-11-05 14:22:15 +00:00
|
|
|
void TestDataSource::testServerGet()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
2020-04-29 14:56:38 +00:00
|
|
|
using namespace KWaylandServer;
|
2014-11-05 14:22:15 +00:00
|
|
|
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWaylandServer::DataDeviceManagerInterface::dataSourceCreated);
|
2014-11-05 14:22:15 +00:00
|
|
|
QVERIFY(dataSourceCreatedSpy.isValid());
|
|
|
|
|
|
|
|
QScopedPointer<DataSource> dataSource(m_dataDeviceManager->createDataSource());
|
|
|
|
QVERIFY(dataSource->isValid());
|
|
|
|
|
|
|
|
QVERIFY(!DataSourceInterface::get(nullptr));
|
|
|
|
QVERIFY(dataSourceCreatedSpy.wait());
|
|
|
|
auto d = dataSourceCreatedSpy.first().first().value<DataSourceInterface*>();
|
|
|
|
|
|
|
|
QCOMPARE(DataSourceInterface::get(d->resource()), d);
|
|
|
|
QVERIFY(!DataSourceInterface::get(nullptr));
|
|
|
|
}
|
|
|
|
|
2014-11-04 14:10:22 +00:00
|
|
|
void TestDataSource::testDestroy()
|
|
|
|
{
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
|
|
|
|
QScopedPointer<DataSource> dataSource(m_dataDeviceManager->createDataSource());
|
|
|
|
QVERIFY(dataSource->isValid());
|
|
|
|
|
|
|
|
connect(m_connection, &ConnectionThread::connectionDied, m_dataDeviceManager, &DataDeviceManager::destroy);
|
|
|
|
connect(m_connection, &ConnectionThread::connectionDied, m_queue, &EventQueue::destroy);
|
|
|
|
connect(m_connection, &ConnectionThread::connectionDied, dataSource.data(), &DataSource::destroy);
|
|
|
|
|
2021-02-25 13:48:11 +00:00
|
|
|
QSignalSpy connectionDiedSpy(m_connection, &KWayland::Client::ConnectionThread::connectionDied);
|
2014-11-04 14:10:22 +00:00
|
|
|
QVERIFY(connectionDiedSpy.isValid());
|
|
|
|
delete m_display;
|
|
|
|
m_display = nullptr;
|
|
|
|
QVERIFY(connectionDiedSpy.wait());
|
|
|
|
|
|
|
|
// now the pool should be destroyed;
|
|
|
|
QVERIFY(!dataSource->isValid());
|
|
|
|
|
|
|
|
// calling destroy again should not fail
|
|
|
|
dataSource->destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
QTEST_GUILESS_MAIN(TestDataSource)
|
|
|
|
#include "test_datasource.moc"
|