~cemil-azizoglu/mir/nested_lifecycle_events_test

« back to all changes in this revision

Viewing changes to tests/acceptance-tests/test_client_surface_events.cpp

  • Committer: Tarmac
  • Author(s): Alan Griffiths
  • Date: 2014-06-20 12:05:55 UTC
  • mfrom: (1701.5.8 mir)
  • Revision ID: tarmac-20140620120555-b7h2bfsczxgcd1lq
orientation API: support for the first orientation use-case (The shell can inform a surface of its orientation).

A second use case follows as Daniel d'Andrada  asked about a client API to query the orientation.

Approved by Alexandros Frantzis, Kevin DuBois, PS Jenkins bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2014 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License version 3 as
 
6
 * published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
 
17
 */
 
18
 
 
19
#include "mir_toolkit/mir_client_library.h"
 
20
#include "mir_toolkit/mir_client_library_debug.h"
 
21
 
 
22
#include "mir/shell/surface_coordinator_wrapper.h"
 
23
 
 
24
#include "mir/scene/surface.h"
 
25
#include "mir/scene/surface_creation_parameters.h"
 
26
 
 
27
#include "mir_test_framework/stubbed_server_configuration.h"
 
28
#include "mir_test_framework/basic_client_server_fixture.h"
 
29
 
 
30
#include <gtest/gtest.h>
 
31
#include <gmock/gmock.h>
 
32
 
 
33
#include <condition_variable>
 
34
#include <chrono>
 
35
#include <mutex>
 
36
 
 
37
namespace mtf = mir_test_framework;
 
38
namespace ms = mir::scene;
 
39
namespace msh = mir::shell;
 
40
 
 
41
using namespace testing;
 
42
 
 
43
namespace
 
44
{
 
45
struct MockSurfaceCoordinator : msh::SurfaceCoordinatorWrapper
 
46
{
 
47
    MockSurfaceCoordinator(std::shared_ptr<ms::SurfaceCoordinator> const& wrapped) :
 
48
        msh::SurfaceCoordinatorWrapper(wrapped)
 
49
    {
 
50
    }
 
51
 
 
52
    std::shared_ptr<ms::Surface> add_surface(
 
53
        ms::SurfaceCreationParameters const& params,
 
54
        ms::Session* session) override
 
55
    {
 
56
        latest_surface = wrapped->add_surface(params, session);
 
57
        return latest_surface;
 
58
    }
 
59
 
 
60
    std::shared_ptr<ms::Surface> latest_surface;
 
61
};
 
62
 
 
63
struct MyConfig : mtf::StubbedServerConfiguration
 
64
{
 
65
    std::shared_ptr<ms::SurfaceCoordinator> wrap_surface_coordinator(
 
66
        std::shared_ptr<ms::SurfaceCoordinator> const& wrapped) override
 
67
    {
 
68
        auto const msc = std::make_shared<MockSurfaceCoordinator>(wrapped);
 
69
        mock_surface_coordinator = msc;
 
70
        return msc;
 
71
    }
 
72
 
 
73
    std::shared_ptr<MockSurfaceCoordinator> the_mock_surface_coordinator() const
 
74
    {
 
75
        return mock_surface_coordinator.lock();
 
76
    }
 
77
 
 
78
    std::shared_ptr<ms::Surface> the_latest_surface() const
 
79
    {
 
80
        return the_mock_surface_coordinator()->latest_surface;
 
81
    }
 
82
 
 
83
    std::weak_ptr<MockSurfaceCoordinator> mock_surface_coordinator;
 
84
};
 
85
 
 
86
using BasicClientServerFixture = mtf::BasicClientServerFixture<MyConfig>;
 
87
 
 
88
struct ClientSurfaceEvents : BasicClientServerFixture
 
89
{
 
90
    MirSurfaceParameters const request_params
 
91
    {
 
92
        __FILE__,
 
93
        640, 480,
 
94
        mir_pixel_format_abgr_8888,
 
95
        mir_buffer_usage_hardware,
 
96
        mir_display_output_id_invalid
 
97
    };
 
98
 
 
99
    MirSurface* surface{nullptr};
 
100
    MirSurface* other_surface;
 
101
 
 
102
    std::mutex last_event_mutex;
 
103
    std::condition_variable last_event_cv;
 
104
    MirEvent last_event{};
 
105
    MirSurface* last_event_surface = nullptr;
 
106
    MirEventDelegate delegate{&event_callback, this};
 
107
 
 
108
    std::shared_ptr<ms::Surface> scene_surface;
 
109
 
 
110
    static void event_callback(MirSurface* surface, MirEvent const* event, void* ctx)
 
111
    {
 
112
        ClientSurfaceEvents* self = static_cast<ClientSurfaceEvents*>(ctx);
 
113
        std::lock_guard<decltype(self->last_event_mutex)> last_event_lock{self->last_event_mutex};
 
114
        self->last_event = *event;
 
115
        self->last_event_surface = surface;
 
116
        self->last_event_cv.notify_one();
 
117
    }
 
118
 
 
119
    bool wait_for_event(MirEventType type, std::chrono::milliseconds delay)
 
120
    {
 
121
        std::unique_lock<decltype(last_event_mutex)> last_event_lock{last_event_mutex};
 
122
        return last_event_cv.wait_for(last_event_lock, delay,
 
123
            [&] { return !!last_event_surface && last_event.type == type; });
 
124
    }
 
125
 
 
126
    void reset_last_event()
 
127
    {
 
128
        std::lock_guard<decltype(last_event_mutex)> last_event_lock{last_event_mutex};
 
129
        memset(&last_event, 0, sizeof last_event);
 
130
        last_event_surface = nullptr;
 
131
    }
 
132
 
 
133
    void SetUp() override
 
134
    {
 
135
        BasicClientServerFixture::SetUp();
 
136
 
 
137
        surface = mir_connection_create_surface_sync(connection, &request_params);
 
138
        mir_surface_set_event_handler(surface, &delegate);
 
139
 
 
140
        scene_surface = server_configuration.the_latest_surface();
 
141
 
 
142
        other_surface = mir_connection_create_surface_sync(connection, &request_params);
 
143
        mir_surface_set_event_handler(other_surface, nullptr);
 
144
 
 
145
        reset_last_event();
 
146
    }
 
147
 
 
148
    void TearDown() override
 
149
    {
 
150
        mir_surface_release_sync(other_surface);
 
151
        mir_surface_release_sync(surface);
 
152
 
 
153
        BasicClientServerFixture::TearDown();
 
154
    }
 
155
};
 
156
}
 
157
 
 
158
TEST_F(ClientSurfaceEvents, surface_receives_state_events)
 
159
{
 
160
    int surface_id = mir_debug_surface_id(surface);
 
161
 
 
162
    {
 
163
        mir_wait_for(mir_surface_set_state(surface, mir_surface_state_fullscreen));
 
164
        mir_wait_for(mir_surface_set_state(other_surface, mir_surface_state_minimized));
 
165
 
 
166
        std::lock_guard<decltype(last_event_mutex)> last_event_lock{last_event_mutex};
 
167
 
 
168
        EXPECT_THAT(last_event_surface, Eq(surface));
 
169
        EXPECT_THAT(last_event.type, Eq(mir_event_type_surface));
 
170
        EXPECT_THAT(last_event.surface.id, Eq(surface_id));
 
171
        EXPECT_THAT(last_event.surface.attrib, Eq(mir_surface_attrib_state));
 
172
        EXPECT_THAT(last_event.surface.value, Eq(mir_surface_state_fullscreen));
 
173
    }
 
174
 
 
175
    {
 
176
        mir_wait_for(mir_surface_set_state(surface, static_cast<MirSurfaceState>(999)));
 
177
 
 
178
        std::lock_guard<decltype(last_event_mutex)> last_event_lock{last_event_mutex};
 
179
 
 
180
        EXPECT_THAT(last_event_surface, Eq(surface));
 
181
        EXPECT_THAT(last_event.type, Eq(mir_event_type_surface));
 
182
        EXPECT_THAT(last_event.surface.id, Eq(surface_id));
 
183
        EXPECT_THAT(last_event.surface.attrib, Eq(mir_surface_attrib_state));
 
184
        EXPECT_THAT(last_event.surface.value, Eq(mir_surface_state_fullscreen));
 
185
    }
 
186
 
 
187
    reset_last_event();
 
188
 
 
189
    {
 
190
        mir_wait_for(mir_surface_set_state(surface, mir_surface_state_minimized));
 
191
 
 
192
        std::lock_guard<decltype(last_event_mutex)> last_event_lock{last_event_mutex};
 
193
 
 
194
        EXPECT_THAT(last_event_surface, Eq(surface));
 
195
        EXPECT_THAT(last_event.type, Eq(mir_event_type_surface));
 
196
        EXPECT_THAT(last_event.surface.id, Eq(surface_id));
 
197
        EXPECT_THAT(last_event.surface.attrib, Eq(mir_surface_attrib_state));
 
198
        EXPECT_THAT(last_event.surface.value, Eq(mir_surface_state_minimized));
 
199
    }
 
200
 
 
201
    reset_last_event();
 
202
 
 
203
    {
 
204
        mir_wait_for(mir_surface_set_state(surface, static_cast<MirSurfaceState>(777)));
 
205
        mir_wait_for(mir_surface_set_state(other_surface, mir_surface_state_maximized));
 
206
 
 
207
        std::lock_guard<decltype(last_event_mutex)> last_event_lock{last_event_mutex};
 
208
 
 
209
        EXPECT_THAT(last_event_surface, IsNull());
 
210
        EXPECT_THAT(last_event.type, Eq(0));
 
211
        EXPECT_THAT(last_event.surface.id, Eq(0));
 
212
        EXPECT_THAT(last_event.surface.attrib, Eq(0));
 
213
        EXPECT_THAT(last_event.surface.value, Eq(0));
 
214
    }
 
215
}
 
216
 
 
217
struct OrientationEvents : ClientSurfaceEvents, ::testing::WithParamInterface<MirOrientation> {};
 
218
 
 
219
TEST_P(OrientationEvents, surface_receives_orientation_events)
 
220
{
 
221
    auto const direction = GetParam();
 
222
 
 
223
    scene_surface->set_orientation(direction);
 
224
 
 
225
    EXPECT_TRUE(wait_for_event(mir_event_type_orientation, std::chrono::seconds(1)));
 
226
 
 
227
    std::lock_guard<decltype(last_event_mutex)> last_event_lock{last_event_mutex};
 
228
 
 
229
    EXPECT_THAT(last_event_surface, Eq(surface));
 
230
    EXPECT_THAT(last_event.type, Eq(mir_event_type_orientation));
 
231
    EXPECT_THAT(last_event.orientation.direction, Eq(direction));
 
232
}
 
233
 
 
234
INSTANTIATE_TEST_CASE_P(ClientSurfaceEvents,
 
235
    OrientationEvents,
 
236
    Values(mir_orientation_normal, mir_orientation_left, mir_orientation_inverted, mir_orientation_right));