File indexing completed on 2024-06-02 05:36:42

0001 /*
0002     SPDX-FileCopyrightText: 2017 David Edmundson <davidedmundson@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 // Qt
0007 #include <QSignalSpy>
0008 #include <QTest>
0009 // KWin
0010 #include "wayland/blur.h"
0011 #include "wayland/clientconnection.h"
0012 #include "wayland/compositor.h"
0013 #include "wayland/display.h"
0014 #include "wayland/filtered_display.h"
0015 
0016 #include "KWayland/Client/blur.h"
0017 #include "KWayland/Client/compositor.h"
0018 #include "KWayland/Client/connection_thread.h"
0019 #include "KWayland/Client/event_queue.h"
0020 #include "KWayland/Client/region.h"
0021 #include "KWayland/Client/registry.h"
0022 #include "KWayland/Client/surface.h"
0023 
0024 #include <wayland-server.h>
0025 
0026 class TestDisplay;
0027 
0028 class TestFilter : public QObject
0029 {
0030     Q_OBJECT
0031 public:
0032     explicit TestFilter(QObject *parent = nullptr);
0033 private Q_SLOTS:
0034     void init();
0035     void cleanup();
0036     void testFilter_data();
0037     void testFilter();
0038 
0039 private:
0040     TestDisplay *m_display;
0041     KWin::CompositorInterface *m_compositorInterface;
0042     KWin::BlurManagerInterface *m_blurManagerInterface;
0043 };
0044 
0045 static const QString s_socketName = QStringLiteral("kwayland-test-wayland-blur-0");
0046 
0047 // The following non-realistic class allows only clients in the m_allowedClients list to access the blur interface
0048 // all other interfaces are allowed
0049 class TestDisplay : public KWin::FilteredDisplay
0050 {
0051 public:
0052     TestDisplay(QObject *parent);
0053     bool allowInterface(KWin::ClientConnection *client, const QByteArray &interfaceName) override;
0054     QList<wl_client *> m_allowedClients;
0055 };
0056 
0057 TestDisplay::TestDisplay(QObject *parent)
0058     : KWin::FilteredDisplay(parent)
0059 {
0060 }
0061 
0062 bool TestDisplay::allowInterface(KWin::ClientConnection *client, const QByteArray &interfaceName)
0063 {
0064     if (interfaceName == "org_kde_kwin_blur_manager") {
0065         return m_allowedClients.contains(*client);
0066     }
0067     return true;
0068 }
0069 
0070 TestFilter::TestFilter(QObject *parent)
0071     : QObject(parent)
0072     , m_display(nullptr)
0073     , m_compositorInterface(nullptr)
0074 {
0075 }
0076 
0077 void TestFilter::init()
0078 {
0079     using namespace KWin;
0080     delete m_display;
0081     m_display = new TestDisplay(this);
0082     m_display->addSocketName(s_socketName);
0083     m_display->start();
0084     QVERIFY(m_display->isRunning());
0085 
0086     m_compositorInterface = new CompositorInterface(m_display, m_display);
0087     m_blurManagerInterface = new BlurManagerInterface(m_display, m_display);
0088 }
0089 
0090 void TestFilter::cleanup()
0091 {
0092 }
0093 
0094 void TestFilter::testFilter_data()
0095 {
0096     QTest::addColumn<bool>("accessAllowed");
0097     QTest::newRow("granted") << true;
0098     QTest::newRow("denied") << false;
0099 }
0100 
0101 void TestFilter::testFilter()
0102 {
0103     QFETCH(bool, accessAllowed);
0104 
0105     // setup connection
0106     std::unique_ptr<KWayland::Client::ConnectionThread> connection(new KWayland::Client::ConnectionThread());
0107     QSignalSpy connectedSpy(connection.get(), &KWayland::Client::ConnectionThread::connected);
0108     connection->setSocketName(s_socketName);
0109 
0110     std::unique_ptr<QThread> thread(new QThread(this));
0111     connection->moveToThread(thread.get());
0112     thread->start();
0113 
0114     connection->initConnection();
0115     QVERIFY(connectedSpy.wait());
0116 
0117     // use low level API as Server::Display::connections only lists connections which have
0118     // been previous fetched via getConnection()
0119     if (accessAllowed) {
0120         wl_client *clientConnection;
0121         wl_client_for_each(clientConnection, wl_display_get_client_list(*m_display))
0122         {
0123             m_display->m_allowedClients << clientConnection;
0124         }
0125     }
0126 
0127     KWayland::Client::EventQueue queue;
0128     queue.setup(connection.get());
0129 
0130     KWayland::Client::Registry registry;
0131     QSignalSpy registryDoneSpy(&registry, &KWayland::Client::Registry::interfacesAnnounced);
0132     QSignalSpy compositorSpy(&registry, &KWayland::Client::Registry::compositorAnnounced);
0133     QSignalSpy blurSpy(&registry, &KWayland::Client::Registry::blurAnnounced);
0134 
0135     registry.setEventQueue(&queue);
0136     registry.create(connection->display());
0137     QVERIFY(registry.isValid());
0138     registry.setup();
0139 
0140     QVERIFY(registryDoneSpy.wait());
0141     QVERIFY(compositorSpy.count() == 1);
0142     QVERIFY(blurSpy.count() == accessAllowed ? 1 : 0);
0143 
0144     thread->quit();
0145     thread->wait();
0146 }
0147 
0148 QTEST_GUILESS_MAIN(TestFilter)
0149 #include "test_wayland_filter.moc"