From 70344cd68de5f6d73bfe17d060d1ad7abcb98704 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 8 Mar 2018 12:32:59 +0100 Subject: Add client-side tests for ivi-application Tests ivi surface creation and configuration. Task-number: QTBUG-66512 Change-Id: Idff60eb99eb34b7fce1c935bd036ef18a8f97d7c Reviewed-by: Andy Nichols --- tests/auto/client/client.pro | 1 + .../auto/client/iviapplication/iviapplication.pro | 5 + .../client/iviapplication/tst_iviapplication.cpp | 142 +++++++++++++++++++++ tests/auto/client/shared/mockcompositor.cpp | 31 +++++ tests/auto/client/shared/mockcompositor.h | 24 ++++ tests/auto/client/shared/mockiviapplication.cpp | 72 +++++++++++ tests/auto/client/shared/mockiviapplication.h | 85 ++++++++++++ tests/auto/client/shared/shared.pri | 3 + 8 files changed, 363 insertions(+) create mode 100644 tests/auto/client/iviapplication/iviapplication.pro create mode 100644 tests/auto/client/iviapplication/tst_iviapplication.cpp create mode 100644 tests/auto/client/shared/mockiviapplication.cpp create mode 100644 tests/auto/client/shared/mockiviapplication.h diff --git a/tests/auto/client/client.pro b/tests/auto/client/client.pro index a668d37d..9fd8fc3f 100644 --- a/tests/auto/client/client.pro +++ b/tests/auto/client/client.pro @@ -2,5 +2,6 @@ TEMPLATE=subdirs SUBDIRS += \ client \ + iviapplication \ xdgshellv6 \ wl_connect diff --git a/tests/auto/client/iviapplication/iviapplication.pro b/tests/auto/client/iviapplication/iviapplication.pro new file mode 100644 index 00000000..32692137 --- /dev/null +++ b/tests/auto/client/iviapplication/iviapplication.pro @@ -0,0 +1,5 @@ +include (../shared/shared.pri) + +TARGET = tst_client_iviapplication +SOURCES += tst_iviapplication.cpp + diff --git a/tests/auto/client/iviapplication/tst_iviapplication.cpp b/tests/auto/client/iviapplication/tst_iviapplication.cpp new file mode 100644 index 00000000..59ff6f55 --- /dev/null +++ b/tests/auto/client/iviapplication/tst_iviapplication.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockcompositor.h" + +#include + +#include + +static const QSize screenSize(1600, 1200); + +class TestWindow : public QWindow +{ +public: + TestWindow() + { + setSurfaceType(QSurface::RasterSurface); + setGeometry(0, 0, 32, 32); + create(); + } +}; + +class tst_WaylandClientIviApplication : public QObject +{ + Q_OBJECT +public: + tst_WaylandClientIviApplication(MockCompositor *c) + : m_compositor(c) + { + QSocketNotifier *notifier = new QSocketNotifier(m_compositor->waylandFileDescriptor(), QSocketNotifier::Read, this); + connect(notifier, &QSocketNotifier::activated, this, &tst_WaylandClientIviApplication::processWaylandEvents); + // connect to the event dispatcher to make sure to flush out the outgoing message queue + connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::awake, this, &tst_WaylandClientIviApplication::processWaylandEvents); + connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, &tst_WaylandClientIviApplication::processWaylandEvents); + } + +public slots: + void processWaylandEvents() + { + m_compositor->processWaylandEvents(); + } + + void cleanup() + { + // make sure the surfaces from the last test are properly cleaned up + // and don't show up as false positives in the next test + QTRY_VERIFY(!m_compositor->surface()); + QTRY_VERIFY(!m_compositor->iviSurface()); + } + +private slots: + void createDestroyWindow(); + void configure(); + void uniqueIviIds(); + +private: + MockCompositor *m_compositor = nullptr; +}; + +void tst_WaylandClientIviApplication::createDestroyWindow() +{ + TestWindow window; + window.show(); + + QTRY_VERIFY(m_compositor->surface()); + QTRY_VERIFY(m_compositor->iviSurface()); + + window.destroy(); + QTRY_VERIFY(!m_compositor->surface()); + QTRY_VERIFY(!m_compositor->iviSurface()); +} + +void tst_WaylandClientIviApplication::configure() +{ + TestWindow window; + window.show(); + + QSharedPointer iviSurface; + QTRY_VERIFY(iviSurface = m_compositor->iviSurface()); + + // Unconfigured ivi surfaces decide their own size + QTRY_COMPARE(window.frameGeometry(), QRect(QPoint(), QSize(32, 32))); + + m_compositor->sendIviSurfaceConfigure(iviSurface, {123, 456}); + QTRY_COMPARE(window.frameGeometry(), QRect(QPoint(), QSize(123, 456))); +} + +void tst_WaylandClientIviApplication::uniqueIviIds() +{ + TestWindow windowA, windowB; + windowA.show(); + windowB.show(); + + QSharedPointer iviSurface0, iviSurface1; + QTRY_VERIFY(iviSurface0 = m_compositor->iviSurface(0)); + QTRY_VERIFY(iviSurface1 = m_compositor->iviSurface(1)); + QTRY_VERIFY(iviSurface0->iviId != iviSurface1->iviId); +} + +int main(int argc, char **argv) +{ + setenv("XDG_RUNTIME_DIR", ".", 1); + setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin + setenv("QT_WAYLAND_SHELL_INTEGRATION", "ivi-shell", 1); + setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1); // window decorations don't make much sense on ivi-application + + MockCompositor compositor; + compositor.setOutputMode(screenSize); + + QGuiApplication app(argc, argv); + compositor.applicationInitialized(); + + tst_WaylandClientIviApplication tc(&compositor); + return QTest::qExec(&tc, argc, argv); +} + +#include diff --git a/tests/auto/client/shared/mockcompositor.cpp b/tests/auto/client/shared/mockcompositor.cpp index 51a95461..9ef08ad9 100644 --- a/tests/auto/client/shared/mockcompositor.cpp +++ b/tests/auto/client/shared/mockcompositor.cpp @@ -32,6 +32,7 @@ #include "mocksurface.h" #include "mockwlshell.h" #include "mockxdgshellv6.h" +#include "mockiviapplication.h" #include @@ -227,6 +228,14 @@ void MockCompositor::sendShellSurfaceConfigure(const QSharedPointer processCommand(command); } +void MockCompositor::sendIviSurfaceConfigure(const QSharedPointer iviSurface, const QSize &size) +{ + Command command = makeCommand(Impl::Compositor::sendIviSurfaceConfigure, m_compositor); + command.parameters << QVariant::fromValue(iviSurface); + command.parameters << QVariant::fromValue(size); + processCommand(command); +} + void MockCompositor::sendXdgToplevelV6Configure(const QSharedPointer toplevel, const QSize &size) { Command command = makeCommand(Impl::Compositor::sendXdgToplevelV6Configure, m_compositor); @@ -267,6 +276,16 @@ QSharedPointer MockCompositor::output(int index) return result; } +QSharedPointer MockCompositor::iviSurface(int index) +{ + QSharedPointer result; + lock(); + if (Impl::IviSurface *toplevel = m_compositor->iviApplication()->iviSurfaces().value(index, nullptr)) + result = toplevel->mockIviSurface(); + unlock(); + return result; +} + QSharedPointer MockCompositor::xdgToplevelV6(int index) { QSharedPointer result; @@ -357,6 +376,7 @@ Compositor::Compositor() m_touch = m_seat->touch(); m_outputs.append(new Output(m_display, QSize(1920, 1080), QPoint(0, 0))); + m_iviApplication.reset(new IviApplication(m_display)); m_wlShell.reset(new WlShell(m_display)); m_xdgShellV6.reset(new XdgShellV6(m_display)); @@ -426,6 +446,11 @@ QVector Compositor::outputs() const return m_outputs; } +IviApplication *Compositor::iviApplication() const +{ + return m_iviApplication.data(); +} + XdgShellV6 *Compositor::xdgShellV6() const { return m_xdgShellV6.data(); @@ -460,6 +485,12 @@ Output *Compositor::resolveOutput(const QVariant &v) return mockOutput ? mockOutput->handle() : nullptr; } +IviSurface *Compositor::resolveIviSurface(const QVariant &v) +{ + QSharedPointer mockIviSurface = v.value>(); + return mockIviSurface ? mockIviSurface->handle() : nullptr; +} + XdgToplevelV6 *Compositor::resolveToplevel(const QVariant &v) { QSharedPointer mockToplevel = v.value>(); diff --git a/tests/auto/client/shared/mockcompositor.h b/tests/auto/client/shared/mockcompositor.h index 5fe51c89..34c20943 100644 --- a/tests/auto/client/shared/mockcompositor.h +++ b/tests/auto/client/shared/mockcompositor.h @@ -30,6 +30,7 @@ #define MOCKCOMPOSITOR_H #include "mockxdgshellv6.h" +#include "mockiviapplication.h" #include #include @@ -54,6 +55,7 @@ class Seat; class DataDeviceManager; class Surface; class Output; +class IviApplication; class WlShell; class XdgShellV6; @@ -72,6 +74,7 @@ public: QVector surfaces() const; QVector outputs() const; + IviApplication *iviApplication() const; XdgShellV6 *xdgShellV6() const; void addSurface(Surface *surface); @@ -99,6 +102,7 @@ public: static void sendSurfaceEnter(void *data, const QList ¶meters); static void sendSurfaceLeave(void *data, const QList ¶meters); static void sendShellSurfaceConfigure(void *data, const QList ¶meters); + static void sendIviSurfaceConfigure(void *data, const QList ¶meters); static void sendXdgToplevelV6Configure(void *data, const QList ¶meters); public: @@ -108,6 +112,7 @@ private: static void bindCompositor(wl_client *client, void *data, uint32_t version, uint32_t id); static Surface *resolveSurface(const QVariant &v); static Output *resolveOutput(const QVariant &v); + static IviSurface *resolveIviSurface(const QVariant &v); static XdgToplevelV6 *resolveToplevel(const QVariant &v); void initShm(); @@ -128,6 +133,7 @@ private: QScopedPointer m_data_device_manager; QVector m_surfaces; QVector m_outputs; + QScopedPointer m_iviApplication; QScopedPointer m_wlShell; QScopedPointer m_xdgShellV6; }; @@ -153,6 +159,22 @@ private: Q_DECLARE_METATYPE(QSharedPointer) +class MockIviSurface +{ +public: + Impl::IviSurface *handle() const { return m_iviSurface; } + const uint iviId; + +private: + MockIviSurface(Impl::IviSurface *iviSurface) : iviId(iviSurface->iviId()), m_iviSurface(iviSurface) {} + friend class Impl::Compositor; + friend class Impl::IviSurface; + + Impl::IviSurface *m_iviSurface; +}; + +Q_DECLARE_METATYPE(QSharedPointer) + class MockXdgToplevelV6 { public: @@ -211,11 +233,13 @@ public: void sendSurfaceEnter(const QSharedPointer &surface, QSharedPointer &output); void sendSurfaceLeave(const QSharedPointer &surface, QSharedPointer &output); void sendShellSurfaceConfigure(const QSharedPointer surface, const QSize &size = QSize(0, 0)); + void sendIviSurfaceConfigure(const QSharedPointer iviSurface, const QSize &size); void sendXdgToplevelV6Configure(const QSharedPointer toplevel, const QSize &size = QSize(0, 0)); void waitForStartDrag(); QSharedPointer surface(); QSharedPointer output(int index = 0); + QSharedPointer iviSurface(int index = 0); QSharedPointer xdgToplevelV6(int index = 0); void lock(); diff --git a/tests/auto/client/shared/mockiviapplication.cpp b/tests/auto/client/shared/mockiviapplication.cpp new file mode 100644 index 00000000..29a30899 --- /dev/null +++ b/tests/auto/client/shared/mockiviapplication.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockiviapplication.h" +#include "mocksurface.h" +#include "mockcompositor.h" + +namespace Impl { + +void Compositor::sendIviSurfaceConfigure(void *data, const QList ¶meters) +{ + Q_UNUSED(data); + IviSurface *iviSurface = resolveIviSurface(parameters.at(0)); + Q_ASSERT(iviSurface && iviSurface->resource()); + QSize size = parameters.at(1).toSize(); + Q_ASSERT(!size.isEmpty()); + iviSurface->send_configure(size.width(), size.height()); +} + +IviSurface::IviSurface(IviApplication *iviApplication, Surface *surface, uint iviId, wl_client *client, uint32_t id) + : QtWaylandServer::ivi_surface(client, id, 1) + , m_surface(surface) + , m_iviApplication(iviApplication) + , m_iviId(iviId) + , m_mockIviSurface(new MockIviSurface(this)) +{ + iviApplication->addIviSurface(this); + surface->map(); +} + +IviSurface::~IviSurface() +{ + m_iviApplication->removeIviSurface(this); + m_mockIviSurface->m_iviSurface = nullptr; +} + +void IviSurface::ivi_surface_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void IviApplication::ivi_application_surface_create(Resource *resource, uint32_t ivi_id, ::wl_resource *surface, uint32_t id) +{ + new IviSurface(this, Surface::fromResource(surface), ivi_id, resource->client(), id); +} + +} // namespace Impl diff --git a/tests/auto/client/shared/mockiviapplication.h b/tests/auto/client/shared/mockiviapplication.h new file mode 100644 index 00000000..4d65eeab --- /dev/null +++ b/tests/auto/client/shared/mockiviapplication.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOCKIVIAPPLICATION_H +#define MOCKIVIAPPLICATION_H + +#include + +#include +#include + +class MockIviSurface; + +namespace Impl { + +class Surface; +class IviApplication; + +class IviSurface : public QtWaylandServer::ivi_surface +{ +public: + IviSurface(IviApplication *iviApplication, Surface *surface, uint iviId, wl_client *client, uint32_t id); + ~IviSurface() override; + IviApplication *iviApplication() const { return m_iviApplication; } + Surface *surface() const { return m_surface; } + uint iviId() const { return m_iviId; } + + QSharedPointer mockIviSurface() const { return m_mockIviSurface; } + +protected: + void ivi_surface_destroy_resource(Resource *) override { delete this; } + void ivi_surface_destroy(Resource *resource) override; + +private: + Surface *m_surface = nullptr; + IviApplication *m_iviApplication = nullptr; + const uint m_iviId = 0; + QSharedPointer m_mockIviSurface; +}; + +class IviApplication : public QtWaylandServer::ivi_application +{ +public: + explicit IviApplication(::wl_display *display) : ivi_application(display, 1) {} + QVector iviSurfaces() const { return m_iviSurfaces; } + +protected: + void ivi_application_surface_create(Resource *resource, uint32_t ivi_id, ::wl_resource *surface, uint32_t id) override; + +private: + void addIviSurface(IviSurface *iviSurface) { m_iviSurfaces.append(iviSurface); } + void removeIviSurface(IviSurface *iviSurface) { m_iviSurfaces.removeOne(iviSurface); } + QVector m_iviSurfaces; + + friend class IviSurface; +}; + +} // namespace Impl + +#endif // MOCKIVIAPPLICATION_H diff --git a/tests/auto/client/shared/shared.pri b/tests/auto/client/shared/shared.pri index 991dd29d..f3cb4d5a 100644 --- a/tests/auto/client/shared/shared.pri +++ b/tests/auto/client/shared/shared.pri @@ -6,6 +6,7 @@ QMAKE_USE += wayland-client wayland-server CONFIG += wayland-scanner WAYLANDSERVERSOURCES += \ + ../../../../src/3rdparty/protocol/ivi-application.xml \ ../../../../src/3rdparty/protocol/wayland.xml \ ../../../../src/3rdparty/protocol/xdg-shell-unstable-v6.xml @@ -14,6 +15,7 @@ INCLUDEPATH += ../shared SOURCES += \ ../shared/mockcompositor.cpp \ ../shared/mockinput.cpp \ + ../shared/mockiviapplication.cpp \ ../shared/mockwlshell.cpp \ ../shared/mockxdgshellv6.cpp \ ../shared/mocksurface.cpp \ @@ -22,6 +24,7 @@ SOURCES += \ HEADERS += \ ../shared/mockcompositor.h \ ../shared/mockinput.h \ + ../shared/mockiviapplication.h \ ../shared/mockwlshell.h \ ../shared/mockxdgshellv6.h \ ../shared/mocksurface.h \ -- cgit v1.2.1