File indexing completed on 2024-11-10 04:56:22

0001 /*
0002     SPDX-FileCopyrightText: 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 // Qt
0008 #include <QHash>
0009 #include <QSignalSpy>
0010 #include <QTest>
0011 #include <QThread>
0012 
0013 #include <wayland-client.h>
0014 
0015 // WaylandServer
0016 #include "wayland/compositor.h"
0017 #include "wayland/display.h"
0018 #include "wayland/screencast_v1.h"
0019 #include "wayland/seat.h"
0020 
0021 #include <KWayland/Client/compositor.h>
0022 #include <KWayland/Client/connection_thread.h>
0023 #include <KWayland/Client/event_queue.h>
0024 #include <KWayland/Client/registry.h>
0025 #include <KWayland/Client/seat.h>
0026 
0027 #include "qwayland-zkde-screencast-unstable-v1.h"
0028 
0029 class ScreencastStreamV1 : public QObject, public QtWayland::zkde_screencast_stream_unstable_v1
0030 {
0031     Q_OBJECT
0032 
0033 public:
0034     ScreencastStreamV1(::zkde_screencast_stream_unstable_v1 *obj, QObject *parent)
0035         : QObject(parent)
0036         , zkde_screencast_stream_unstable_v1(obj)
0037     {
0038     }
0039 
0040     void zkde_screencast_stream_unstable_v1_created(uint32_t node) override
0041     {
0042         Q_EMIT created(node);
0043     }
0044 
0045 Q_SIGNALS:
0046     void created(quint32 node);
0047 };
0048 
0049 class ScreencastV1 : public QObject, public QtWayland::zkde_screencast_unstable_v1
0050 {
0051     Q_OBJECT
0052 
0053 public:
0054     ScreencastV1(QObject *parent)
0055         : QObject(parent)
0056     {
0057     }
0058 
0059     ScreencastStreamV1 *createWindowStream(const QString &uuid)
0060     {
0061         return new ScreencastStreamV1(stream_window(uuid, 2), this);
0062     }
0063 };
0064 
0065 class TestScreencastV1Interface : public QObject
0066 {
0067     Q_OBJECT
0068 
0069 public:
0070     TestScreencastV1Interface()
0071     {
0072     }
0073 
0074     ~TestScreencastV1Interface() override;
0075 
0076 private Q_SLOTS:
0077     void initTestCase();
0078     void testCreate();
0079 
0080 private:
0081     KWayland::Client::ConnectionThread *m_connection;
0082     KWayland::Client::EventQueue *m_queue = nullptr;
0083     ScreencastV1 *m_screencast = nullptr;
0084 
0085     KWin::ScreencastV1Interface *m_screencastInterface = nullptr;
0086 
0087     QPointer<KWin::ScreencastStreamV1Interface> m_triggered = nullptr;
0088     QThread *m_thread;
0089     KWin::Display *m_display = nullptr;
0090 };
0091 
0092 static const QString s_socketName = QStringLiteral("kwin-wayland-server-screencast-test-0");
0093 
0094 void TestScreencastV1Interface::initTestCase()
0095 {
0096     delete m_display;
0097     m_display = new KWin::Display(this);
0098     m_display->addSocketName(s_socketName);
0099     m_display->start();
0100     QVERIFY(m_display->isRunning());
0101 
0102     // setup connection
0103     m_connection = new KWayland::Client::ConnectionThread;
0104     QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
0105     m_connection->setSocketName(s_socketName);
0106 
0107     m_thread = new QThread(this);
0108     m_connection->moveToThread(m_thread);
0109     m_thread->start();
0110 
0111     m_connection->initConnection();
0112     QVERIFY(connectedSpy.wait());
0113 
0114     m_queue = new KWayland::Client::EventQueue(this);
0115     QVERIFY(!m_queue->isValid());
0116     m_queue->setup(m_connection);
0117     QVERIFY(m_queue->isValid());
0118 
0119     KWayland::Client::Registry registry;
0120 
0121     QSignalSpy screencastSpy(&registry, &KWayland::Client::Registry::interfacesAnnounced);
0122     m_screencastInterface = new KWin::ScreencastV1Interface(m_display, this);
0123     connect(m_screencastInterface,
0124             &KWin::ScreencastV1Interface::windowScreencastRequested,
0125             this,
0126             [this](KWin::ScreencastStreamV1Interface *stream, const QString &winid) {
0127                 stream->sendCreated(123);
0128                 m_triggered = stream;
0129             });
0130 
0131     connect(&registry,
0132             &KWayland::Client::Registry::interfaceAnnounced,
0133             this,
0134             [this, &registry](const QByteArray &interfaceName, quint32 name, quint32 version) {
0135                 if (interfaceName != "zkde_screencast_unstable_v1")
0136                     return;
0137                 m_screencast = new ScreencastV1(this);
0138                 m_screencast->init(&*registry, name, version);
0139             });
0140     registry.setEventQueue(m_queue);
0141     registry.create(m_connection->display());
0142     QVERIFY(registry.isValid());
0143     registry.setup();
0144     wl_display_flush(m_connection->display());
0145 
0146     QVERIFY(m_screencastInterface);
0147     QVERIFY(m_screencast || screencastSpy.wait());
0148     QVERIFY(m_screencast);
0149 }
0150 
0151 TestScreencastV1Interface::~TestScreencastV1Interface()
0152 {
0153     delete m_queue;
0154     m_queue = nullptr;
0155 
0156     if (m_thread) {
0157         m_thread->quit();
0158         m_thread->wait();
0159         delete m_thread;
0160         m_thread = nullptr;
0161     }
0162     m_connection->deleteLater();
0163     m_connection = nullptr;
0164 
0165     delete m_display;
0166 }
0167 
0168 void TestScreencastV1Interface::testCreate()
0169 {
0170     auto stream = m_screencast->createWindowStream("3");
0171     QVERIFY(stream);
0172 
0173     QSignalSpy spyWorking(stream, &ScreencastStreamV1::created);
0174     QVERIFY(spyWorking.count() || spyWorking.wait());
0175     QVERIFY(m_triggered);
0176 
0177     QSignalSpy spyStop(m_triggered, &KWin::ScreencastStreamV1Interface::finished);
0178     stream->close();
0179     QVERIFY(spyStop.count() || spyStop.wait());
0180 }
0181 
0182 QTEST_GUILESS_MAIN(TestScreencastV1Interface)
0183 
0184 #include "test_screencast.moc"