Mir

Merge lp:~alan-griffiths/mir/message-passing-api into lp:mir

Proposed by Alan Griffiths
Status: Work in progress
Proposed branch: lp:~alan-griffiths/mir/message-passing-api
Merge into: lp:mir
Diff against target: 474 lines (+332/-1)
14 files modified
include/client/mir_toolkit/mir_client_library.h (+99/-0)
include/server/mir/frontend/session.h (+2/-0)
include/server/mir/shell/surface.h (+14/-1)
include/shared/mir_toolkit/client_types.h (+11/-0)
include/test/mir_test_doubles/mock_shell_session.h (+3/-0)
include/test/mir_test_doubles/stub_session.h (+3/-0)
include/test/mir_test_doubles/stub_shell_session.h (+4/-0)
src/server/scene/application_session.cpp (+5/-0)
src/server/scene/application_session.h (+2/-0)
src/server/scene/surface_impl.cpp (+5/-0)
src/server/scene/surface_impl.h (+2/-0)
tests/acceptance-tests/CMakeLists.txt (+1/-0)
tests/acceptance-tests/test_message_passing.cpp (+177/-0)
tests/unit-tests/frontend/test_session_mediator.cpp (+4/-0)
To merge this branch: bzr merge lp:~alan-griffiths/mir/message-passing-api
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+198422@code.launchpad.net

Commit message

client API, shell: introduce functions for passing "opaque" messages

Description of the change

client API, shell: introduce functions for passing "opaque" messages

To post a comment you must log in.
1285. By Alan Griffiths

Basic skeleton of running server in test process

1286. By Alan Griffiths

Tidier code

1287. By Alan Griffiths

Tidier code and connection creation

1288. By Alan Griffiths

Stubbed first MessagePassing test

1289. By Alan Griffiths

merge lp:~mir-team/mir/development-branch

Unmerged revisions

1289. By Alan Griffiths

merge lp:~mir-team/mir/development-branch

1288. By Alan Griffiths

Stubbed first MessagePassing test

1287. By Alan Griffiths

Tidier code and connection creation

1286. By Alan Griffiths

Tidier code

1285. By Alan Griffiths

Basic skeleton of running server in test process

1284. By Alan Griffiths

Add tentative MessageTarget interface

1283. By Alan Griffiths

Add handle_message(...) to frontend::Session interface

1282. By Alan Griffiths

Minimal messaging API

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/client/mir_toolkit/mir_client_library.h'
2--- include/client/mir_toolkit/mir_client_library.h 2013-12-02 16:48:04 +0000
3+++ include/client/mir_toolkit/mir_client_library.h 2013-12-12 17:14:21 +0000
4@@ -205,6 +205,105 @@
5 MirSurfaceParameters const *params);
6
7 /**
8+ * Request a new unrealized Mir surface on the supplied connection with the
9+ * supplied parameters. The returned handle remains valid until the surface
10+ * has been released.
11+ * \warning callback could be called from another thread. You must do any
12+ * locking appropriate to protect your data accessed in the
13+ * callback.
14+ * \param [in] connection The connection
15+ * \param [in] surface_parameters Request surface parameters
16+ * \param [in] surface_callback Callback function to be invoked when
17+ * request completes
18+ * \param [in,out] surface_context User data passed to the surface_callback
19+ * function
20+ * \param [in] message_callback Callback function when surface receives
21+ * messages
22+ * \param [in,out] message_context User data passed to the message_callback
23+ * function
24+ * \return A handle that can be passed to
25+ * mir_wait_for
26+ */
27+MirWaitHandle *mir_connection_create_unrealized_surface(
28+ MirConnection *connection,
29+ MirSurfaceParameters const *surface_parameters,
30+ mir_surface_callback surface_callback,
31+ void *surface_context,
32+ mir_surface_message_callback message_callback,
33+ void *message_context);
34+
35+/**
36+ * Create a surface like in mir_connection_create_unrealized_surface(), but
37+ * also wait for creation to complete and return the resulting surface.
38+ * \param [in] connection The connection
39+ * \param [in] params Parameters describing the desired surface
40+ * \param [in] message_callback Callback function when surface receives
41+ * messages
42+ * \param [in,out] message_context User data passed to the message_callback
43+ * function
44+ * \return The resulting surface
45+ */
46+MirSurface *mir_connection_create_unrealized_surface_sync(
47+ MirConnection *connection,
48+ MirSurfaceParameters const *params,
49+ mir_surface_message_callback message_callback,
50+ void *message_context);
51+
52+/**
53+ * Realize an unrealized Mir surface. The returned handle remains valid until
54+ * the surface has been released.
55+ * \warning callback could be called from another thread. You must do any
56+ * locking appropriate to protect your data accessed in the
57+ * callback.
58+ * \param [in] surface The surface
59+ * \param [in] surface_callback Callback function to be invoked when
60+ * request completes
61+ * \param [in,out] surface_context User data passed to the surface_callback
62+ * function
63+ * \return A handle that can be passed to
64+ * mir_wait_for
65+ */
66+MirWaitHandle *mir_surface_realize(
67+ MirSurface *surface,
68+ mir_surface_callback surface_callback,
69+ void *surface_context);
70+
71+/**
72+ * Realize an unrealized Mir surface.
73+ * \param [in] surface The surface
74+ */
75+void mir_surface_realize_sync(MirSurface *surface);
76+
77+/**
78+ * Send a message from the surface.
79+ * \param [in] surface The surface
80+ * \param [in] size number of bytes to send
81+ * \param [in] data buffer containing bytes to send
82+ */
83+void mir_surface_send_message(
84+ MirSurface *surface,
85+ size_t size,
86+ void const *data);
87+
88+/**
89+ * Set the message handler to be called when messages arrive for a surface.
90+ * \warning event_handler could be called from another thread. You must do
91+ * any locking appropriate to protect your data accessed in the
92+ * callback. There is also a chance that different messages will be
93+ * called back in different threads, for the same surface,
94+ * simultaneously.
95+ * \param [in] surface The surface
96+ * \param [in] message_callback Callback function when surface receives
97+ * messages
98+ * \param [in,out] message_context User data passed to the message_callback
99+ * function
100+ */
101+void mir_surface_set_message_handler(
102+ MirSurface *surface,
103+ mir_surface_message_callback message_callback,
104+ void *message_context);
105+
106+/**
107 * Set the event handler to be called when events arrive for a surface.
108 * \warning event_handler could be called from another thread. You must do
109 * any locking appropriate to protect your data accessed in the
110
111=== modified file 'include/server/mir/frontend/session.h'
112--- include/server/mir/frontend/session.h 2013-08-28 03:41:48 +0000
113+++ include/server/mir/frontend/session.h 2013-12-12 17:14:21 +0000
114@@ -60,6 +60,8 @@
115 virtual void send_display_config(graphics::DisplayConfiguration const&) = 0;
116 virtual int configure_surface(SurfaceId id, MirSurfaceAttrib attrib, int value) = 0;
117
118+ virtual void handle_message(SurfaceId id, std::size_t size, void const* data) = 0;
119+
120 protected:
121 Session() = default;
122 Session(Session const&) = delete;
123
124=== modified file 'include/server/mir/shell/surface.h'
125--- include/server/mir/shell/surface.h 2013-12-04 09:57:35 +0000
126+++ include/server/mir/shell/surface.h 2013-12-12 17:14:21 +0000
127@@ -34,7 +34,20 @@
128 {
129 class InputTargeter;
130
131-class Surface : public frontend::Surface, public shell::SurfaceBufferAccess
132+class MessageTarget
133+{
134+public:
135+ MessageTarget() = default;
136+ virtual ~MessageTarget() = default;
137+
138+ virtual void send_message(size_t size, void const* data) = 0;
139+
140+private:
141+ MessageTarget(MessageTarget const&) = delete;
142+ MessageTarget& operator=(MessageTarget const&) = delete;
143+};
144+
145+class Surface : public frontend::Surface, public shell::SurfaceBufferAccess, public MessageTarget
146 {
147 public:
148 virtual std::string name() const = 0;
149
150=== modified file 'include/shared/mir_toolkit/client_types.h'
151--- include/shared/mir_toolkit/client_types.h 2013-12-02 16:48:04 +0000
152+++ include/shared/mir_toolkit/client_types.h 2013-12-12 17:14:21 +0000
153@@ -73,6 +73,17 @@
154 typedef void (*mir_surface_callback)(MirSurface *surface, void *client_context);
155
156 /**
157+ * Callback for handling surface messages
158+ * \param [in] surface the surface being updated
159+ * \param [in,out] client_context context provided by client in calling
160+ * mir_connect
161+ * \param [in] size number of bytes received
162+ * \param [in] data buffer containing bytes received
163+ */
164+typedef void (*mir_surface_message_callback)(MirSurface *surface,
165+ void *client_context, size_t size, void const *data);
166+
167+/**
168 * Callback member of MirEventDelegate for handling of events.
169 * \param [in] surface The surface on which an event has occurred
170 * \param [in] event The event to be handled
171
172=== modified file 'include/test/mir_test_doubles/mock_shell_session.h'
173--- include/test/mir_test_doubles/mock_shell_session.h 2013-12-02 16:48:04 +0000
174+++ include/test/mir_test_doubles/mock_shell_session.h 2013-12-12 17:14:21 +0000
175@@ -51,6 +51,9 @@
176 MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int));
177
178 MOCK_METHOD1(set_lifecycle_state, void(MirLifecycleState state));
179+ void handle_message(frontend::SurfaceId /*id*/, std::size_t /*size*/, void const* /*data*/) override
180+ {
181+ }
182 };
183
184 }
185
186=== modified file 'include/test/mir_test_doubles/stub_session.h'
187--- include/test/mir_test_doubles/stub_session.h 2013-08-28 03:41:48 +0000
188+++ include/test/mir_test_doubles/stub_session.h 2013-12-12 17:14:21 +0000
189@@ -65,6 +65,9 @@
190 void send_display_config(graphics::DisplayConfiguration const&)
191 {
192 }
193+ void handle_message(frontend::SurfaceId /*id*/, std::size_t /*size*/, void const* /*data*/) override
194+ {
195+ }
196 };
197
198 }
199
200=== modified file 'include/test/mir_test_doubles/stub_shell_session.h'
201--- include/test/mir_test_doubles/stub_shell_session.h 2013-12-02 16:48:04 +0000
202+++ include/test/mir_test_doubles/stub_shell_session.h 2013-12-12 17:14:21 +0000
203@@ -75,6 +75,10 @@
204 void set_lifecycle_state(MirLifecycleState /*state*/)
205 {
206 }
207+
208+ void handle_message(frontend::SurfaceId /*id*/, std::size_t /*size*/, void const* /*data*/) override
209+ {
210+ }
211 };
212
213 }
214
215=== modified file 'src/server/scene/application_session.cpp'
216--- src/server/scene/application_session.cpp 2013-12-02 16:48:04 +0000
217+++ src/server/scene/application_session.cpp 2013-12-12 17:14:21 +0000
218@@ -171,3 +171,8 @@
219 {
220 event_sink->handle_lifecycle_event(state);
221 }
222+
223+void ms::ApplicationSession::handle_message(mf::SurfaceId /*id*/, std::size_t /*size*/, void const* /*data*/)
224+{
225+ // TODO
226+}
227
228=== modified file 'src/server/scene/application_session.h'
229--- src/server/scene/application_session.h 2013-12-02 16:48:04 +0000
230+++ src/server/scene/application_session.h 2013-12-12 17:14:21 +0000
231@@ -71,6 +71,8 @@
232
233 void set_lifecycle_state(MirLifecycleState state);
234
235+ void handle_message(frontend::SurfaceId id, std::size_t size, void const* data);
236+
237 protected:
238 ApplicationSession(ApplicationSession const&) = delete;
239 ApplicationSession& operator=(ApplicationSession const&) = delete;
240
241=== modified file 'src/server/scene/surface_impl.cpp'
242--- src/server/scene/surface_impl.cpp 2013-12-06 13:32:41 +0000
243+++ src/server/scene/surface_impl.cpp 2013-12-12 17:14:21 +0000
244@@ -266,3 +266,8 @@
245 {
246 surface->set_alpha(alpha);
247 }
248+
249+void ms::SurfaceImpl::send_message(size_t /*size*/, void const* /*data*/)
250+{
251+ // TODO - implement
252+}
253
254=== modified file 'src/server/scene/surface_impl.h'
255--- src/server/scene/surface_impl.h 2013-12-06 13:32:41 +0000
256+++ src/server/scene/surface_impl.h 2013-12-12 17:14:21 +0000
257@@ -91,6 +91,8 @@
258 virtual void set_rotation(float degrees, glm::vec3 const& axis);
259 virtual void set_alpha(float alpha);
260
261+ virtual void send_message(size_t size, void const* data);
262+
263 private:
264 bool set_type(MirSurfaceType t); // Use configure() to make public changes
265 bool set_state(MirSurfaceState s);
266
267=== modified file 'tests/acceptance-tests/CMakeLists.txt'
268--- tests/acceptance-tests/CMakeLists.txt 2013-12-02 16:48:04 +0000
269+++ tests/acceptance-tests/CMakeLists.txt 2013-12-12 17:14:21 +0000
270@@ -6,6 +6,7 @@
271 SOURCES
272
273 test_client_library.cpp
274+ test_message_passing.cpp
275 test_surfaceloop.cpp
276 test_test_framework.cpp
277 test_focus_selection.cpp
278
279=== added file 'tests/acceptance-tests/test_message_passing.cpp'
280--- tests/acceptance-tests/test_message_passing.cpp 1970-01-01 00:00:00 +0000
281+++ tests/acceptance-tests/test_message_passing.cpp 2013-12-12 17:14:21 +0000
282@@ -0,0 +1,177 @@
283+/*
284+ * Copyright © 2013 Canonical Ltd.
285+ *
286+ * This program is free software: you can redistribute it and/or modify it
287+ * under the terms of the GNU General Public License version 3,
288+ * as published by the Free Software Foundation.
289+ *
290+ * This program is distributed in the hope that it will be useful,
291+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
292+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
293+ * GNU General Public License for more details.
294+ *
295+ * You should have received a copy of the GNU General Public License
296+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
297+ *
298+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
299+ */
300+
301+#include "mir_toolkit/mir_client_library.h"
302+
303+#include "mir/frontend/connector.h"
304+#include "mir/display_server.h"
305+#include "mir/run_mir.h"
306+
307+#include "mir_test_framework/testing_server_configuration.h"
308+
309+#include <gtest/gtest.h>
310+#include <gmock/gmock.h>
311+
312+#include <condition_variable>
313+#include <mutex>
314+#include <thread>
315+
316+namespace
317+{
318+// TODO we're only using part of TestingServerConfiguration - so that ought to be factored out
319+struct TestMessagePassingServerConfiguration : mir_test_framework::TestingServerConfiguration
320+{
321+private:
322+ using mir_test_framework::TestingServerConfiguration::exec;
323+ using mir_test_framework::TestingServerConfiguration::on_exit;
324+};
325+
326+struct MessagePassing : testing::Test
327+{
328+ MessagePassing();
329+ ~MessagePassing();
330+
331+ void SetUp();
332+ void TearDown();
333+
334+ TestMessagePassingServerConfiguration server_config;
335+ std::string new_connection();
336+
337+private:
338+ mir::DisplayServer* start_mir_server();
339+
340+ std::thread server_thread;
341+ mir::DisplayServer* const display_server;
342+};
343+
344+MessagePassing::MessagePassing() :
345+ server_config(),
346+ display_server{start_mir_server()}
347+{
348+}
349+
350+void MessagePassing::SetUp()
351+{
352+ ASSERT_TRUE(display_server);
353+}
354+
355+std::string MessagePassing::new_connection()
356+{
357+ char endpoint[128] = {0};
358+ sprintf(endpoint, "fd://%d", server_config.the_connector()->client_socket_fd());
359+
360+ return endpoint;
361+}
362+
363+void MessagePassing::TearDown()
364+{
365+ display_server->stop();
366+}
367+
368+MessagePassing::~MessagePassing()
369+{
370+ if (server_thread.joinable()) server_thread.join();
371+}
372+
373+mir::DisplayServer* MessagePassing::start_mir_server()
374+{
375+ std::mutex mutex;
376+ std::condition_variable cv;
377+ mir::DisplayServer* display_server{nullptr};
378+
379+ server_thread = std::thread([&]
380+ {
381+ try
382+ {
383+ mir::run_mir(server_config, [&](mir::DisplayServer& ds)
384+ {
385+ std::unique_lock<std::mutex> lock(mutex);
386+ display_server = &ds;
387+ cv.notify_one();
388+ });
389+ }
390+ catch (std::exception const& e)
391+ {
392+ FAIL() << e.what();
393+ }
394+ });
395+
396+ using namespace std::chrono;
397+ auto const time_limit = system_clock::now() + seconds(2);
398+
399+ std::unique_lock<std::mutex> lock(mutex);
400+
401+ while (!display_server && time_limit > system_clock::now())
402+ cv.wait_until(lock, time_limit);
403+
404+ return display_server;
405+}
406+
407+void test_surface_message_callback(
408+ MirSurface* /*surface*/,
409+ void* /*client_context*/,
410+ size_t /*size*/,
411+ void const* /*data*/)
412+{
413+
414+}
415+}
416+
417+MirSurface *mir_connection_create_unrealized_surface_sync(
418+ MirConnection */*connection*/,
419+ MirSurfaceParameters const */*params*/,
420+ mir_surface_message_callback /*message_callback*/,
421+ void */*message_context*/)
422+{
423+ // TODO implement and put in right place
424+ return nullptr;
425+}
426+
427+void mir_surface_realize_sync(MirSurface */*surface*/)
428+{
429+ // TODO implement and put in right place
430+}
431+
432+
433+
434+TEST_F(MessagePassing, create_and_realize_surface)
435+{
436+ auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
437+ ASSERT_TRUE(mir_connection_is_valid(connection));
438+
439+ MirSurfaceParameters params;
440+
441+ auto const surface = mir_connection_create_unrealized_surface_sync(
442+ connection,
443+ &params,
444+ test_surface_message_callback,
445+ this);
446+
447+ // TODO what *should* this return for an unrealized surface?
448+// EXPECT_TRUE(mir_surface_is_valid(surface));
449+
450+ mir_surface_realize_sync(surface);
451+
452+ // TODO this should pass
453+// EXPECT_TRUE(mir_surface_is_valid(surface));
454+
455+ // TODO code
456+// mir_surface_release_sync(surface);
457+
458+ mir_connection_release(connection);
459+}
460
461=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
462--- tests/unit-tests/frontend/test_session_mediator.cpp 2013-12-04 09:40:30 +0000
463+++ tests/unit-tests/frontend/test_session_mediator.cpp 2013-12-12 17:14:21 +0000
464@@ -137,6 +137,10 @@
465 mock_surfaces.erase(surface);
466 }
467
468+ void handle_message(mf::SurfaceId /*id*/, std::size_t /*size*/, void const* /*data*/) override
469+ {
470+ }
471+
472 mtd::StubSurfaceBuilder surface_builder;
473 std::shared_ptr<mtd::MockFrontendSurface> mock_surface;
474 std::map<mf::SurfaceId, std::shared_ptr<mtd::MockFrontendSurface>> mock_surfaces;

Subscribers

People subscribed via source and target branches