Mir

Merge lp:~alan-griffiths/mir/spike-passing-out-client-fds into lp:mir

Proposed by Alan Griffiths
Status: Superseded
Proposed branch: lp:~alan-griffiths/mir/spike-passing-out-client-fds
Merge into: lp:mir
Prerequisite: lp:~alan-griffiths/mir/cleanup-receive_file_descriptors
Diff against target: 1171 lines (+524/-40)
34 files modified
examples/render_surfaces.cpp (+1/-0)
include/client/mir_toolkit/mir_connection.h (+19/-0)
include/server/mir/frontend/connection_context.h (+55/-0)
include/server/mir/frontend/connection_creator.h (+5/-1)
include/server/mir/frontend/connector.h (+8/-1)
include/server/mir/frontend/protobuf_connection_creator.h (+3/-1)
include/server/mir/frontend/session.h (+1/-3)
include/shared/mir_toolkit/client_types.h (+11/-0)
include/test/mir_test_doubles/mock_scene_session.h (+2/-0)
include/test/mir_test_doubles/stub_ipc_factory.h (+3/-2)
src/client/mir_connection.cpp (+34/-0)
src/client/mir_connection.h (+8/-0)
src/client/mir_connection_api.cpp (+18/-0)
src/client/rpc/mir_socket_rpc_channel.cpp (+7/-0)
src/server/frontend/CMakeLists.txt (+1/-0)
src/server/frontend/connection_context.cpp (+36/-0)
src/server/frontend/default_configuration.cpp (+5/-3)
src/server/frontend/protobuf_connection_creator.cpp (+4/-2)
src/server/frontend/protobuf_ipc_factory.h (+3/-1)
src/server/frontend/protobuf_message_processor.cpp (+11/-0)
src/server/frontend/protobuf_message_processor.h (+1/-0)
src/server/frontend/published_socket_connector.cpp (+12/-4)
src/server/frontend/published_socket_connector.h (+5/-2)
src/server/frontend/session_mediator.cpp (+40/-4)
src/server/frontend/session_mediator.h (+15/-7)
src/server/scene/application_session.h (+2/-0)
src/shared/protobuf/mir_protobuf.proto (+13/-1)
tests/acceptance-tests/CMakeLists.txt (+1/-0)
tests/acceptance-tests/test_trust_session_helper.cpp (+91/-0)
tests/integration-tests/test_display_server_main_loop_events.cpp (+1/-0)
tests/integration-tests/test_session.cpp (+1/-0)
tests/unit-tests/frontend/test_session_mediator.cpp (+103/-6)
tests/unit-tests/frontend/test_session_mediator_android.cpp (+2/-1)
tests/unit-tests/frontend/test_session_mediator_mesa.cpp (+2/-1)
To merge this branch: bzr merge lp:~alan-griffiths/mir/spike-passing-out-client-fds
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+218074@code.launchpad.net

This proposal has been superseded by a proposal from 2014-05-07.

Commit message

frontend, client: sort out the "wiring" to allow clients to get a connected FD.

Description of the change

frontend, client: sort out the "wiring" to allow clients to get a connected FD.

This is largely a "proof of concept" of an approach required by trust sessions - allowing a client to request a socket FD for use by a process that it then launches.

To post a comment you must log in.
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks ok overall. It takes some effort to follow the logic through the many layers, but this is a pre-existing problem with this part of the code.

60 + int fd_for_client_handled_by(std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const;
61 +
62 + void handle_client_connect(std::shared_ptr<Session> const& session) const { connect_handler(session); }

This part confused me a bit because I was trying to figure out the relationship between the two operations for the same session. It took me some time to realize that one is (primarily) used by the parent session and the other in the child sessions. Is there is a use case in which a session is both a parent of some sessions and a child of another session?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/render_surfaces.cpp'
2--- examples/render_surfaces.cpp 2014-05-05 03:36:45 +0000
3+++ examples/render_surfaces.cpp 2014-05-07 14:18:03 +0000
4@@ -241,6 +241,7 @@
5 void start() {}
6 void stop() {}
7 int client_socket_fd() const override { return 0; }
8+ int client_socket_fd(std::function<void(std::shared_ptr<mf::Session> const&)> const&) const override { return 0; }
9 void remove_endpoint() const override { }
10 };
11
12
13=== modified file 'include/client/mir_toolkit/mir_connection.h'
14--- include/client/mir_toolkit/mir_connection.h 2014-03-31 14:36:08 +0000
15+++ include/client/mir_toolkit/mir_connection.h 2014-05-07 14:18:03 +0000
16@@ -169,6 +169,25 @@
17 MirConnection* connection, MirPixelFormat* formats,
18 unsigned const int format_size, unsigned int *num_valid_formats);
19
20+/**
21+ * Allocate some FDs for trusted clients to connect on
22+ *
23+ * Trust session helpers need to allocate connection FDs it will pass to
24+ * trusted clients to use when connecting to the server. The server can
25+ * then associate them with the trust session.
26+ *
27+ * \warning This API is tentative until the implementation of trust sessions is complete
28+ * \param [in] connection The connection
29+ * \param [in] no_of_fds The number of fds to allocate
30+ * \param [in] callback Callback invoked when request completes
31+ * \param [in,out] context User data passed to the callback function
32+ * \return A handle that can be passed to mir_wait_for
33+ */
34+MirWaitHandle* mir_connection_new_fds_for_trusted_clients(
35+ MirConnection* connection,
36+ unsigned int no_of_fds,
37+ mir_client_fd_callback callback,
38+ void * context);
39
40 #ifdef __cplusplus
41 }
42
43=== added file 'include/server/mir/frontend/connection_context.h'
44--- include/server/mir/frontend/connection_context.h 1970-01-01 00:00:00 +0000
45+++ include/server/mir/frontend/connection_context.h 2014-05-07 14:18:03 +0000
46@@ -0,0 +1,55 @@
47+/*
48+ * Copyright © 014 Canonical Ltd.
49+ *
50+ * This program is free software: you can redistribute it and/or modify it
51+ * under the terms of the GNU General Public License version 3,
52+ * as published by the Free Software Foundation.
53+ *
54+ * This program is distributed in the hope that it will be useful,
55+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
56+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57+ * GNU General Public License for more details.
58+ *
59+ * You should have received a copy of the GNU General Public License
60+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
61+ *
62+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
63+ */
64+
65+#ifndef MIR_FRONTEND_CONNECTION_CONTEXT_H_
66+#define MIR_FRONTEND_CONNECTION_CONTEXT_H_
67+
68+#include <functional>
69+#include <memory>
70+
71+namespace mir
72+{
73+namespace frontend
74+{
75+class Connector;
76+class Session;
77+
78+class ConnectionContext
79+{
80+public:
81+ ConnectionContext() = delete;
82+ ConnectionContext(const ConnectionContext&) = default;
83+ ConnectionContext& operator=(const ConnectionContext&) = default;
84+ ConnectionContext(Connector const* connector) :
85+ ConnectionContext([](std::shared_ptr<Session> const&){}, connector) {}
86+ ConnectionContext(
87+ std::function<void(std::shared_ptr<Session> const& session)> const connect_handler,
88+ Connector const* connector);
89+
90+ int fd_for_new_client(std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const;
91+
92+ void handle_client_connect(std::shared_ptr<Session> const& session) const { connect_handler(session); }
93+
94+private:
95+ std::function<void(std::shared_ptr<Session> const& session)> const connect_handler;
96+ Connector const* const connector;
97+};
98+}
99+}
100+
101+#endif /* MIR_FRONTEND_CONNECTION_CONTEXT_H_ */
102
103=== modified file 'include/server/mir/frontend/connection_creator.h'
104--- include/server/mir/frontend/connection_creator.h 2014-05-05 03:36:45 +0000
105+++ include/server/mir/frontend/connection_creator.h 2014-05-07 14:18:03 +0000
106@@ -27,10 +27,14 @@
107 {
108 namespace frontend
109 {
110+class ConnectionContext;
111+
112 class ConnectionCreator
113 {
114 public:
115- virtual void create_connection_for(std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket) = 0;
116+ virtual void create_connection_for(
117+ std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket,
118+ ConnectionContext const& connection_context) = 0;
119
120 protected:
121 ConnectionCreator() = default;
122
123=== modified file 'include/server/mir/frontend/connector.h'
124--- include/server/mir/frontend/connector.h 2013-10-15 08:53:10 +0000
125+++ include/server/mir/frontend/connector.h 2014-05-07 14:18:03 +0000
126@@ -1,5 +1,5 @@
127 /*
128- * Copyright © 2012 Canonical Ltd.
129+ * Copyright © 2012-2014 Canonical Ltd.
130 *
131 * This program is free software: you can redistribute it and/or modify it
132 * under the terms of the GNU General Public License version 3,
133@@ -19,10 +19,15 @@
134 #ifndef MIR_FRONTEND_CONNECTOR_H_
135 #define MIR_FRONTEND_CONNECTOR_H_
136
137+#include <functional>
138+#include <memory>
139+
140 namespace mir
141 {
142 namespace frontend
143 {
144+class Session;
145+
146 /// Handle client process connections
147 class Connector
148 {
149@@ -33,6 +38,8 @@
150 virtual int client_socket_fd() const = 0;
151 virtual void remove_endpoint() const = 0;
152
153+ virtual int client_socket_fd(std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const = 0;
154+
155 protected:
156 Connector() = default;
157 virtual ~Connector() = default;
158
159=== modified file 'include/server/mir/frontend/protobuf_connection_creator.h'
160--- include/server/mir/frontend/protobuf_connection_creator.h 2014-05-05 03:36:45 +0000
161+++ include/server/mir/frontend/protobuf_connection_creator.h 2014-05-07 14:18:03 +0000
162@@ -49,7 +49,9 @@
163 std::shared_ptr<MessageProcessorReport> const& report);
164 ~ProtobufConnectionCreator() noexcept;
165
166- void create_connection_for(std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket);
167+ void create_connection_for(
168+ std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket,
169+ ConnectionContext const& connection_context) override;
170
171 virtual std::shared_ptr<detail::MessageProcessor> create_processor(
172 std::shared_ptr<detail::ProtobufMessageSender> const& sender,
173
174=== modified file 'include/server/mir/frontend/session.h'
175--- include/server/mir/frontend/session.h 2014-04-15 05:31:19 +0000
176+++ include/server/mir/frontend/session.h 2014-05-07 14:18:03 +0000
177@@ -22,8 +22,6 @@
178 #include "mir_toolkit/common.h"
179 #include "mir/frontend/surface_id.h"
180
181-#include <mutex>
182-#include <atomic>
183 #include <memory>
184 #include <string>
185
186@@ -46,7 +44,7 @@
187 class Session
188 {
189 public:
190- virtual ~Session() {}
191+ virtual ~Session() = default;
192
193 virtual SurfaceId create_surface(scene::SurfaceCreationParameters const& params) = 0;
194 virtual void destroy_surface(SurfaceId surface) = 0;
195
196=== modified file 'include/shared/mir_toolkit/client_types.h'
197--- include/shared/mir_toolkit/client_types.h 2014-03-11 16:19:27 +0000
198+++ include/shared/mir_toolkit/client_types.h 2014-05-07 14:18:03 +0000
199@@ -104,6 +104,17 @@
200 MirConnection* connection, void* context);
201
202 /**
203+ * Callback called when a request for client file descriptors completes
204+ * \param [in] connection The connection associated with the display change
205+ * \param [in] count The number of FDs allocated
206+ * \param [in] fds Array of FDs
207+ * \param [in,out] context The context provided by client
208+ */
209+
210+typedef void (*mir_client_fd_callback)(
211+ MirConnection* connection, size_t count, int const* fds, void* context);
212+
213+/**
214 * MirBufferUsage specifies how a surface can and will be used. A "hardware"
215 * surface can be used for OpenGL accelerated rendering. A "software" surface
216 * is one that can be addressed in main memory and blitted to directly.
217
218=== modified file 'include/test/mir_test_doubles/mock_scene_session.h'
219--- include/test/mir_test_doubles/mock_scene_session.h 2014-04-15 05:31:19 +0000
220+++ include/test/mir_test_doubles/mock_scene_session.h 2014-05-07 14:18:03 +0000
221@@ -52,6 +52,8 @@
222 MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int));
223
224 MOCK_METHOD1(set_lifecycle_state, void(MirLifecycleState state));
225+
226+ MOCK_METHOD0(child_connect_handler, std::function<void(std::shared_ptr<frontend::Session> const& session)>());
227 };
228
229 }
230
231=== modified file 'include/test/mir_test_doubles/stub_ipc_factory.h'
232--- include/test/mir_test_doubles/stub_ipc_factory.h 2014-05-06 03:33:05 +0000
233+++ include/test/mir_test_doubles/stub_ipc_factory.h 2014-05-07 14:18:03 +0000
234@@ -45,8 +45,9 @@
235 }
236
237 std::shared_ptr<protobuf::DisplayServer> make_ipc_server(
238- mir::frontend::SessionCredentials const&,
239- std::shared_ptr<frontend::EventSink> const&) override
240+ mir::frontend::SessionCredentials const& /*creds*/,
241+ std::shared_ptr<mir::frontend::EventSink> const& /*sink*/,
242+ mir::frontend::ConnectionContext const& /*connection_context*/) override
243 {
244 return server;
245 }
246
247=== modified file 'src/client/mir_connection.cpp'
248--- src/client/mir_connection.cpp 2014-03-06 06:05:17 +0000
249+++ src/client/mir_connection.cpp 2014-05-07 14:18:03 +0000
250@@ -304,6 +304,40 @@
251 return &drm_auth_magic_wait_handle;
252 }
253
254+MirWaitHandle* MirConnection::new_fds_for_trusted_clients(
255+ unsigned int no_of_fds,
256+ mir_client_fd_callback callback,
257+ void * context)
258+{
259+ mir::protobuf::SocketFDRequest request;
260+ request.set_number(no_of_fds);
261+
262+ server.new_fds_for_trusted_clients(
263+ nullptr,
264+ &request,
265+ &socket_fd_response,
266+ google::protobuf::NewCallback(this, &MirConnection::done_fds_for_trusted_clients,
267+ callback, context));
268+
269+ return &fds_for_trusted_clients_wait_handle;
270+}
271+
272+void MirConnection::done_fds_for_trusted_clients(
273+ mir_client_fd_callback callback,
274+ void* context)
275+{
276+ auto const size = socket_fd_response.fd_size();
277+
278+ std::vector<int> fds;
279+ fds.reserve(size);
280+
281+ for (auto i = 0; i != size; ++i)
282+ fds.push_back(socket_fd_response.fd(i));
283+
284+ callback(this, size, fds.data(), context);
285+ fds_for_trusted_clients_wait_handle.result_received();
286+}
287+
288 bool MirConnection::is_valid(MirConnection *connection)
289 {
290 {
291
292=== modified file 'src/client/mir_connection.h'
293--- src/client/mir_connection.h 2014-03-06 06:05:17 +0000
294+++ src/client/mir_connection.h 2014-05-07 14:18:03 +0000
295@@ -123,6 +123,11 @@
296
297 bool set_extra_platform_data(std::vector<int> const& extra_platform_data);
298
299+ MirWaitHandle* new_fds_for_trusted_clients(
300+ unsigned int no_of_fds,
301+ mir_client_fd_callback callback,
302+ void * context);
303+
304 std::shared_ptr<google::protobuf::RpcChannel> rpc_channel() const
305 {
306 return channel;
307@@ -142,6 +147,7 @@
308 mir::protobuf::ConnectParameters connect_parameters;
309 mir::protobuf::DRMAuthMagicStatus drm_auth_magic_status;
310 mir::protobuf::DisplayConfiguration display_configuration_response;
311+ mir::protobuf::SocketFD socket_fd_response;
312
313 std::shared_ptr<mir::client::ClientPlatformFactory> const client_platform_factory;
314 std::shared_ptr<mir::client::ClientPlatform> platform;
315@@ -155,6 +161,7 @@
316 MirWaitHandle disconnect_wait_handle;
317 MirWaitHandle drm_auth_magic_wait_handle;
318 MirWaitHandle configure_display_wait_handle;
319+ MirWaitHandle fds_for_trusted_clients_wait_handle;
320
321 std::mutex release_wait_handle_guard;
322 std::vector<MirWaitHandle*> release_wait_handles;
323@@ -174,6 +181,7 @@
324 void connected(mir_connected_callback callback, void * context);
325 void released(SurfaceRelease );
326 void done_drm_auth_magic(mir_drm_auth_magic_callback callback, void* context);
327+ void done_fds_for_trusted_clients(mir_client_fd_callback callback, void* context);
328 bool validate_user_display_config(MirDisplayConfiguration* config);
329 };
330
331
332=== modified file 'src/client/mir_connection_api.cpp'
333--- src/client/mir_connection_api.cpp 2014-03-31 14:36:08 +0000
334+++ src/client/mir_connection_api.cpp 2014-05-07 14:18:03 +0000
335@@ -272,6 +272,24 @@
336 }
337 }
338
339+MirWaitHandle* mir_connection_new_fds_for_trusted_clients(
340+ MirConnection* connection,
341+ unsigned int no_of_fds,
342+ mir_client_fd_callback callback,
343+ void * context)
344+{
345+ try
346+ {
347+ return connection ?
348+ connection->new_fds_for_trusted_clients(no_of_fds, callback, context) :
349+ nullptr;
350+ }
351+ catch (std::exception const&)
352+ {
353+ return nullptr;
354+ }
355+}
356+
357 MirEGLNativeDisplayType mir_connection_get_egl_native_display(
358 MirConnection* connection)
359 {
360
361=== modified file 'src/client/rpc/mir_socket_rpc_channel.cpp'
362--- src/client/rpc/mir_socket_rpc_channel.cpp 2014-05-05 03:36:45 +0000
363+++ src/client/rpc/mir_socket_rpc_channel.cpp 2014-05-07 14:18:03 +0000
364@@ -166,6 +166,7 @@
365 mir::protobuf::Surface* surface = nullptr;
366 mir::protobuf::Buffer* buffer = nullptr;
367 mir::protobuf::Platform* platform = nullptr;
368+ mir::protobuf::SocketFD* socket_fd = nullptr;
369
370 if (message_type == "mir.protobuf.Buffer")
371 {
372@@ -193,9 +194,15 @@
373 if (connection && connection->has_platform())
374 platform = connection->mutable_platform();
375 }
376+ else if (message_type == "mir.protobuf.SocketFD")
377+ {
378+ socket_fd = static_cast<mir::protobuf::SocketFD*>(response);
379+ }
380+
381 receive_any_file_descriptors_for(surface);
382 receive_any_file_descriptors_for(buffer);
383 receive_any_file_descriptors_for(platform);
384+ receive_any_file_descriptors_for(socket_fd);
385 }
386
387 complete->Run();
388
389=== modified file 'src/server/frontend/CMakeLists.txt'
390--- src/server/frontend/CMakeLists.txt 2014-05-05 03:36:45 +0000
391+++ src/server/frontend/CMakeLists.txt 2014-05-07 14:18:03 +0000
392@@ -2,6 +2,7 @@
393 FRONTEND_SOURCES
394
395 client_buffer_tracker.cpp
396+ connection_context.cpp
397 session_mediator.cpp
398 protobuf_message_processor.cpp
399 protobuf_responder.cpp
400
401=== added file 'src/server/frontend/connection_context.cpp'
402--- src/server/frontend/connection_context.cpp 1970-01-01 00:00:00 +0000
403+++ src/server/frontend/connection_context.cpp 2014-05-07 14:18:03 +0000
404@@ -0,0 +1,36 @@
405+/*
406+ * Copyright © 2014 Canonical Ltd.
407+ *
408+ * This program is free software: you can redistribute it and/or modify it
409+ * under the terms of the GNU General Public License version 3,
410+ * as published by the Free Software Foundation.
411+ *
412+ * This program is distributed in the hope that it will be useful,
413+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
415+ * GNU General Public License for more details.
416+ *
417+ * You should have received a copy of the GNU General Public License
418+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
419+ *
420+ * Authored By: Alan Griffiths <alan@octopull.co.uk>
421+ */
422+
423+#include "mir/frontend/connection_context.h"
424+
425+#include "mir/frontend/connector.h"
426+
427+namespace mf = mir::frontend;
428+
429+mf::ConnectionContext::ConnectionContext(
430+ std::function<void(std::shared_ptr<Session> const& session)> const connect_handler,
431+ Connector const* connector) :
432+ connect_handler(connect_handler),
433+ connector(connector)
434+{
435+}
436+
437+int mf::ConnectionContext::fd_for_new_client(std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const
438+{
439+ return connector->client_socket_fd(connect_handler);
440+}
441
442=== modified file 'src/server/frontend/default_configuration.cpp'
443--- src/server/frontend/default_configuration.cpp 2014-05-06 03:33:05 +0000
444+++ src/server/frontend/default_configuration.cpp 2014-05-07 14:18:03 +0000
445@@ -70,9 +70,10 @@
446 std::shared_ptr<mf::Screencast> const screencast;
447 std::shared_ptr<mf::SessionAuthorizer> const session_authorizer;
448
449- virtual std::shared_ptr<mir::protobuf::DisplayServer> make_ipc_server(
450+ std::shared_ptr<mir::protobuf::DisplayServer> make_ipc_server(
451 mf::SessionCredentials const& creds,
452- std::shared_ptr<mf::EventSink> const& sink) override
453+ std::shared_ptr<mf::EventSink> const& sink,
454+ mf::ConnectionContext const& connection_context) override
455 {
456 std::shared_ptr<mf::DisplayChanger> changer;
457 std::shared_ptr<mf::Screencast> effective_screencast;
458@@ -104,7 +105,8 @@
459 sm_report,
460 sink,
461 resource_cache(),
462- effective_screencast);
463+ effective_screencast,
464+ connection_context);
465 }
466
467 virtual std::shared_ptr<mf::ResourceCache> resource_cache()
468
469=== modified file 'src/server/frontend/protobuf_connection_creator.cpp'
470--- src/server/frontend/protobuf_connection_creator.cpp 2014-05-05 03:36:45 +0000
471+++ src/server/frontend/protobuf_connection_creator.cpp 2014-05-07 14:18:03 +0000
472@@ -54,7 +54,9 @@
473 return next_session_id.fetch_add(1);
474 }
475
476-void mf::ProtobufConnectionCreator::create_connection_for(std::shared_ptr<ba::local::stream_protocol::socket> const& socket)
477+void mf::ProtobufConnectionCreator::create_connection_for(
478+ std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket,
479+ ConnectionContext const& connection_context)
480 {
481 auto const messenger = std::make_shared<detail::SocketMessenger>(socket);
482 auto const creds = messenger->client_creds();
483@@ -68,7 +70,7 @@
484 auto const event_sink = std::make_shared<detail::EventSender>(messenger);
485 auto const msg_processor = create_processor(
486 message_sender,
487- ipc_factory->make_ipc_server(creds, event_sink),
488+ ipc_factory->make_ipc_server(creds, event_sink, connection_context),
489 report);
490
491 const auto& connection = std::make_shared<mfd::SocketConnection>(messenger, next_id(), connections, msg_processor);
492
493=== modified file 'src/server/frontend/protobuf_ipc_factory.h'
494--- src/server/frontend/protobuf_ipc_factory.h 2014-05-05 03:36:45 +0000
495+++ src/server/frontend/protobuf_ipc_factory.h 2014-05-07 14:18:03 +0000
496@@ -31,6 +31,7 @@
497 }
498 namespace frontend
499 {
500+class ConnectionContext;
501 class EventSink;
502 class ResourceCache;
503 class MessageProcessorReport;
504@@ -41,7 +42,8 @@
505 public:
506 virtual std::shared_ptr<protobuf::DisplayServer> make_ipc_server(
507 SessionCredentials const& creds,
508- std::shared_ptr<EventSink> const& sink) = 0;
509+ std::shared_ptr<EventSink> const& sink,
510+ ConnectionContext const& connection_context) = 0;
511
512 virtual std::shared_ptr<ResourceCache> resource_cache() = 0;
513
514
515=== modified file 'src/server/frontend/protobuf_message_processor.cpp'
516--- src/server/frontend/protobuf_message_processor.cpp 2014-03-06 06:05:17 +0000
517+++ src/server/frontend/protobuf_message_processor.cpp 2014-05-07 14:18:03 +0000
518@@ -57,6 +57,7 @@
519 template<> struct result_ptr_t<::mir::protobuf::Connection> { typedef ::mir::protobuf::Connection* type; };
520 template<> struct result_ptr_t<::mir::protobuf::Surface> { typedef ::mir::protobuf::Surface* type; };
521 template<> struct result_ptr_t<::mir::protobuf::Screencast> { typedef ::mir::protobuf::Screencast* type; };
522+template<> struct result_ptr_t<mir::protobuf::SocketFD> { typedef ::mir::protobuf::SocketFD* type; };
523
524 template<>
525 void invoke(
526@@ -173,6 +174,10 @@
527 {
528 invoke(this, display_server.get(), &protobuf::DisplayServer::release_screencast, invocation);
529 }
530+ else if ("new_fds_for_trusted_clients" == invocation.method_name())
531+ {
532+ invoke(this, display_server.get(), &protobuf::DisplayServer::new_fds_for_trusted_clients, invocation);
533+ }
534 else if ("disconnect" == invocation.method_name())
535 {
536 invoke(this, display_server.get(), &protobuf::DisplayServer::disconnect, invocation);
537@@ -239,3 +244,9 @@
538
539 sender->send_response(id, response, {buffer_fd});
540 }
541+
542+void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::SocketFD* response)
543+{
544+ const auto& fd = extract_fds_from(response);
545+ sender->send_response(id, response, {fd});
546+}
547
548=== modified file 'src/server/frontend/protobuf_message_processor.h'
549--- src/server/frontend/protobuf_message_processor.h 2014-03-06 06:05:17 +0000
550+++ src/server/frontend/protobuf_message_processor.h 2014-05-07 14:18:03 +0000
551@@ -54,6 +54,7 @@
552 void send_response(::google::protobuf::uint32 id, protobuf::Surface* response);
553 void send_response(::google::protobuf::uint32 id, std::shared_ptr<protobuf::Buffer> response);
554 void send_response(::google::protobuf::uint32 id, mir::protobuf::Screencast* response);
555+ void send_response(::google::protobuf::uint32 id, mir::protobuf::SocketFD* response);
556
557 private:
558 bool dispatch(Invocation const& invocation);
559
560=== modified file 'src/server/frontend/published_socket_connector.cpp'
561--- src/server/frontend/published_socket_connector.cpp 2014-05-05 03:36:45 +0000
562+++ src/server/frontend/published_socket_connector.cpp 2014-05-07 14:18:03 +0000
563@@ -19,6 +19,7 @@
564 #include "published_socket_connector.h"
565 #include "mir/frontend/protobuf_connection_creator.h"
566
567+#include "mir/frontend/connection_context.h"
568 #include "mir/frontend/connector_report.h"
569
570 #include <boost/signals2.hpp>
571@@ -138,7 +139,7 @@
572 {
573 if (!ec)
574 {
575- create_session_for(socket);
576+ create_session_for(socket, [](std::shared_ptr<mf::Session> const&) {});
577 }
578 start_accept();
579 }
580@@ -199,14 +200,21 @@
581 io_service.reset();
582 }
583
584-void mf::BasicConnector::create_session_for(std::shared_ptr<boost::asio::local::stream_protocol::socket> const& server_socket) const
585+void mf::BasicConnector::create_session_for(
586+ std::shared_ptr<boost::asio::local::stream_protocol::socket> const& server_socket,
587+ std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const
588 {
589 report->creating_session_for(server_socket->native_handle());
590- connection_creator->create_connection_for(server_socket);
591+ connection_creator->create_connection_for(server_socket, {connect_handler, this});
592 }
593
594 int mf::BasicConnector::client_socket_fd() const
595 {
596+ return client_socket_fd([](std::shared_ptr<mf::Session> const&) {});
597+}
598+
599+int mf::BasicConnector::client_socket_fd(std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const
600+{
601 enum { server, client, size };
602 int socket_fd[size];
603
604@@ -222,7 +230,7 @@
605
606 report->creating_socket_pair(socket_fd[server], socket_fd[client]);
607
608- create_session_for(server_socket);
609+ create_session_for(server_socket, connect_handler);
610
611 return socket_fd[client];
612 }
613
614=== modified file 'src/server/frontend/published_socket_connector.h'
615--- src/server/frontend/published_socket_connector.h 2014-05-05 03:36:45 +0000
616+++ src/server/frontend/published_socket_connector.h 2014-05-07 14:18:03 +0000
617@@ -56,10 +56,13 @@
618 void stop() override;
619 int client_socket_fd() const override;
620 void remove_endpoint() const override;
621-
622+ int client_socket_fd(std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const override;
623
624 protected:
625- void create_session_for(std::shared_ptr<boost::asio::local::stream_protocol::socket> const& server_socket) const;
626+ void create_session_for(
627+ std::shared_ptr<boost::asio::local::stream_protocol::socket> const& server_socket,
628+ std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const;
629+
630 boost::asio::io_service mutable io_service;
631 boost::asio::io_service::work work;
632 std::shared_ptr<ConnectorReport> const report;
633
634=== modified file 'src/server/frontend/session_mediator.cpp'
635--- src/server/frontend/session_mediator.cpp 2014-04-15 05:31:19 +0000
636+++ src/server/frontend/session_mediator.cpp 2014-05-07 14:18:03 +0000
637@@ -67,7 +67,8 @@
638 std::shared_ptr<SessionMediatorReport> const& report,
639 std::shared_ptr<EventSink> const& sender,
640 std::shared_ptr<ResourceCache> const& resource_cache,
641- std::shared_ptr<Screencast> const& screencast) :
642+ std::shared_ptr<Screencast> const& screencast,
643+ ConnectionContext const& connection_context) :
644 client_pid(client_pid),
645 shell(shell),
646 graphics_platform(graphics_platform),
647@@ -76,7 +77,8 @@
648 report(report),
649 event_sink(sender),
650 resource_cache(resource_cache),
651- screencast(screencast)
652+ screencast(screencast),
653+ connection_context(connection_context)
654 {
655 }
656
657@@ -97,10 +99,12 @@
658 {
659 report->session_connect_called(request->application_name());
660
661+ auto const session = shell->open_session(client_pid, request->application_name(), event_sink);
662 {
663- std::unique_lock<std::mutex> lock(session_mutex);
664- weak_session = shell->open_session(client_pid, request->application_name(), event_sink);
665+ std::lock_guard<std::mutex> lock(session_mutex);
666+ weak_session = session;
667 }
668+ connection_context.handle_client_connect(session);
669
670 auto ipc_package = graphics_platform->get_ipc_package();
671 auto platform = response->mutable_platform();
672@@ -411,6 +415,38 @@
673 done->Run();
674 }
675
676+void mf::SessionMediator::new_fds_for_trusted_clients(
677+ ::google::protobuf::RpcController* ,
678+ ::mir::protobuf::SocketFDRequest const* parameters,
679+ ::mir::protobuf::SocketFD* response,
680+ ::google::protobuf::Closure* done)
681+{
682+ {
683+ std::unique_lock<std::mutex> lock(session_mutex);
684+ auto session = weak_session.lock();
685+
686+ if (session.get() == nullptr)
687+ BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));
688+
689+ // TODO write a handler that connects the new session to our trust session
690+ auto const connect_handler = [](std::shared_ptr<frontend::Session> const&) {};
691+
692+ auto const fds_requested = parameters->number();
693+
694+ // < 1 is illogical, > 42 is unreasonable
695+ if (fds_requested < 1 || fds_requested > 42)
696+ BOOST_THROW_EXCEPTION(std::runtime_error("number of fds requested out of range"));
697+
698+ for (auto i = 0; i != fds_requested; ++i)
699+ {
700+ auto const fd = connection_context.fd_for_new_client(connect_handler);
701+ response->add_fd(fd);
702+ }
703+ }
704+
705+ done->Run();
706+}
707+
708 void mf::SessionMediator::drm_auth_magic(
709 google::protobuf::RpcController* /*controller*/,
710 const mir::protobuf::DRMMagic* request,
711
712=== modified file 'src/server/frontend/session_mediator.h'
713--- src/server/frontend/session_mediator.h 2014-03-06 06:05:17 +0000
714+++ src/server/frontend/session_mediator.h 2014-05-07 14:18:03 +0000
715@@ -16,11 +16,11 @@
716 * Authored by: Alan Griffiths <alan@octopull.co.uk>
717 */
718
719-
720 #ifndef MIR_FRONTEND_SESSION_MEDIATOR_H_
721 #define MIR_FRONTEND_SESSION_MEDIATOR_H_
722
723 #include "mir_protobuf.pb.h"
724+#include "mir/frontend/connection_context.h"
725 #include "mir/frontend/surface_id.h"
726 #include "mir_toolkit/common.h"
727
728@@ -40,7 +40,6 @@
729 class GraphicBufferAllocator;
730 }
731
732-
733 /// Frontend interface. Mediates the interaction between client
734 /// processes and the core of the mir system.
735 namespace frontend
736@@ -59,6 +58,7 @@
737 class SessionMediator : public mir::protobuf::DisplayServer
738 {
739 public:
740+
741 SessionMediator(
742 pid_t client_pid,
743 std::shared_ptr<Shell> const& shell,
744@@ -68,7 +68,8 @@
745 std::shared_ptr<SessionMediatorReport> const& report,
746 std::shared_ptr<EventSink> const& event_sink,
747 std::shared_ptr<ResourceCache> const& resource_cache,
748- std::shared_ptr<Screencast> const& screencast);
749+ std::shared_ptr<Screencast> const& screencast,
750+ ConnectionContext const& connection_context);
751
752 ~SessionMediator() noexcept;
753
754@@ -112,17 +113,17 @@
755 void create_screencast(google::protobuf::RpcController*,
756 const mir::protobuf::ScreencastParameters*,
757 mir::protobuf::Screencast*,
758- google::protobuf::Closure* done);
759+ google::protobuf::Closure* done) override;
760
761 void release_screencast(google::protobuf::RpcController*,
762 const mir::protobuf::ScreencastId*,
763 mir::protobuf::Void*,
764- google::protobuf::Closure* done);
765+ google::protobuf::Closure* done) override;
766
767 void screencast_buffer(google::protobuf::RpcController*,
768 const mir::protobuf::ScreencastId*,
769 mir::protobuf::Buffer*,
770- google::protobuf::Closure* done);
771+ google::protobuf::Closure* done) override;
772
773 /* Platform specific requests */
774 void drm_auth_magic(google::protobuf::RpcController* controller,
775@@ -130,6 +131,12 @@
776 mir::protobuf::DRMAuthMagicStatus* response,
777 google::protobuf::Closure* done) override;
778
779+ void new_fds_for_trusted_clients(
780+ ::google::protobuf::RpcController* controller,
781+ ::mir::protobuf::SocketFDRequest const* parameters,
782+ ::mir::protobuf::SocketFD* response,
783+ ::google::protobuf::Closure* done) override;
784+
785 private:
786 void pack_protobuf_buffer(protobuf::Buffer& protobuf_buffer,
787 graphics::Buffer* graphics_buffer,
788@@ -153,10 +160,11 @@
789
790 std::mutex session_mutex;
791 std::weak_ptr<Session> weak_session;
792+
793+ ConnectionContext const connection_context;
794 };
795
796 }
797 }
798
799-
800 #endif /* MIR_FRONTEND_SESSION_MEDIATOR_H_ */
801
802=== modified file 'src/server/scene/application_session.h'
803--- src/server/scene/application_session.h 2014-04-15 05:31:19 +0000
804+++ src/server/scene/application_session.h 2014-05-07 14:18:03 +0000
805@@ -21,7 +21,9 @@
806
807 #include "mir/scene/session.h"
808
809+#include <atomic>
810 #include <map>
811+#include <mutex>
812
813 namespace mir
814 {
815
816=== modified file 'src/shared/protobuf/mir_protobuf.proto'
817--- src/shared/protobuf/mir_protobuf.proto 2014-03-11 16:19:27 +0000
818+++ src/shared/protobuf/mir_protobuf.proto 2014-05-07 14:18:03 +0000
819@@ -175,6 +175,18 @@
820 optional string error = 127;
821 }
822
823+message SocketFDRequest {
824+ required int32 number = 1;
825+}
826+
827+
828+message SocketFD {
829+ repeated sint32 fd = 1;
830+ optional int32 fds_on_side_channel = 2;
831+
832+ optional string error = 127;
833+}
834+
835 service DisplayServer {
836 // Platform independent requests
837 rpc connect(ConnectParameters) returns (Connection);
838@@ -194,5 +206,5 @@
839 rpc create_screencast(ScreencastParameters) returns (Screencast);
840 rpc screencast_buffer(ScreencastId) returns (Buffer);
841 rpc release_screencast(ScreencastId) returns (Void);
842+ rpc new_fds_for_trusted_clients(SocketFDRequest) returns (SocketFD);
843 }
844-
845
846=== modified file 'tests/acceptance-tests/CMakeLists.txt'
847--- tests/acceptance-tests/CMakeLists.txt 2014-05-05 03:36:45 +0000
848+++ tests/acceptance-tests/CMakeLists.txt 2014-05-07 14:18:03 +0000
849@@ -31,6 +31,7 @@
850 test_protobuf.cpp
851 test_client_screencast.cpp
852 test_client_surface_swap_buffers.cpp
853+ test_trust_session_helper.cpp
854 ${GENERATED_PROTOBUF_SRCS}
855 ${GENERATED_PROTOBUF_HDRS}
856 )
857
858=== added file 'tests/acceptance-tests/test_trust_session_helper.cpp'
859--- tests/acceptance-tests/test_trust_session_helper.cpp 1970-01-01 00:00:00 +0000
860+++ tests/acceptance-tests/test_trust_session_helper.cpp 2014-05-07 14:18:03 +0000
861@@ -0,0 +1,91 @@
862+/*
863+ * Copyright © 2014 Canonical Ltd.
864+ *
865+ * This program is free software: you can redistribute it and/or modify it
866+ * under the terms of the GNU General Public License version 3,
867+ * as published by the Free Software Foundation.
868+ *
869+ * This program is distributed in the hope that it will be useful,
870+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
871+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
872+ * GNU General Public License for more details.
873+ *
874+ * You should have received a copy of the GNU General Public License
875+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
876+ *
877+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
878+ */
879+
880+#include "mir_toolkit/mir_client_library.h"
881+
882+#include "mir_test_framework/stubbed_server_configuration.h"
883+#include "mir_test_framework/in_process_server.h"
884+
885+#include <gtest/gtest.h>
886+#include <gmock/gmock.h>
887+
888+#include <algorithm>
889+#include <condition_variable>
890+#include <mutex>
891+
892+namespace
893+{
894+using DemoServerConfiguration = mir_test_framework::StubbedServerConfiguration;
895+
896+struct TrustSessionHelper : mir_test_framework::InProcessServer
897+{
898+ DemoServerConfiguration my_server_config;
899+
900+ mir::DefaultServerConfiguration& server_config() override { return my_server_config; }
901+
902+ void SetUp()
903+ {
904+ mir_test_framework::InProcessServer::SetUp();
905+ connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
906+ }
907+
908+ void TearDown()
909+ {
910+ mir_connection_release(connection);
911+ mir_test_framework::InProcessServer::TearDown();
912+ }
913+
914+ MirConnection* connection = nullptr;
915+
916+ static std::size_t const arbritary_fd_request_count = 3;
917+
918+ std::mutex mutex;
919+ std::size_t actual_fd_count = 0;
920+ int actual_fds[arbritary_fd_request_count] = {};
921+ std::condition_variable cv;
922+ bool called_back = false;
923+
924+ bool wait_for_callback(std::chrono::milliseconds timeout)
925+ {
926+ std::unique_lock<decltype(mutex)> lock(mutex);
927+ return cv.wait_for(lock, timeout, [this]{ return called_back; });
928+ }
929+};
930+
931+void client_fd_callback(MirConnection*, size_t count, int const* fds, void* context)
932+{
933+ auto const self = static_cast<TrustSessionHelper*>(context);
934+
935+ std::unique_lock<decltype(self->mutex)> lock(self->mutex);
936+ self->actual_fd_count = count;
937+
938+ std::copy(fds, fds+count, self->actual_fds);
939+ self->called_back = true;
940+ self->cv.notify_one();
941+}
942+}
943+
944+using namespace testing;
945+
946+TEST_F(TrustSessionHelper, gets_fds_for_trusted_clients)
947+{
948+ mir_connection_new_fds_for_trusted_clients(connection, arbritary_fd_request_count, &client_fd_callback, this);
949+ EXPECT_TRUE(wait_for_callback(std::chrono::milliseconds(500)));
950+
951+ EXPECT_THAT(actual_fd_count, Eq(arbritary_fd_request_count));
952+}
953
954=== modified file 'tests/integration-tests/test_display_server_main_loop_events.cpp'
955--- tests/integration-tests/test_display_server_main_loop_events.cpp 2014-03-06 06:05:17 +0000
956+++ tests/integration-tests/test_display_server_main_loop_events.cpp 2014-05-07 14:18:03 +0000
957@@ -63,6 +63,7 @@
958 * to silence gmock warnings.
959 */
960 int client_socket_fd() const { return 0; }
961+ int client_socket_fd(std::function<void(std::shared_ptr<mf::Session> const&)> const&) const override { return 0; }
962 void remove_endpoint() const {}
963 };
964
965
966=== modified file 'tests/integration-tests/test_session.cpp'
967--- tests/integration-tests/test_session.cpp 2014-04-15 05:31:19 +0000
968+++ tests/integration-tests/test_session.cpp 2014-05-07 14:18:03 +0000
969@@ -69,6 +69,7 @@
970 void start() {}
971 void stop() {}
972 int client_socket_fd() const override { return 0; }
973+ int client_socket_fd(std::function<void(std::shared_ptr<mf::Session> const&)> const&) const override { return 0; }
974 void remove_endpoint() const override { }
975 };
976
977
978=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
979--- tests/unit-tests/frontend/test_session_mediator.cpp 2014-05-01 07:13:02 +0000
980+++ tests/unit-tests/frontend/test_session_mediator.cpp 2014-05-07 14:18:03 +0000
981@@ -41,6 +41,7 @@
982 #include "mir_test_doubles/null_screencast.h"
983 #include "mir_test/display_config_matchers.h"
984 #include "mir_test/fake_shared.h"
985+#include "mir/frontend/connector.h"
986 #include "mir/frontend/event_sink.h"
987
988 #include "gmock_set_arg.h"
989@@ -86,10 +87,18 @@
990 MOCK_METHOD1(for_each_output, void(std::function<void(mg::UserDisplayConfigurationOutput&)>));
991 };
992
993-}
994-
995-namespace
996+struct MockConnector : public mf::Connector
997 {
998+public:
999+ void start() override {}
1000+ void stop() override {}
1001+
1002+ int client_socket_fd() const override { return 0; }
1003+ void remove_endpoint() const override {}
1004+
1005+ MOCK_CONST_METHOD1(client_socket_fd, int (std::function<void(std::shared_ptr<mf::Session> const&)> const&));
1006+};
1007+
1008 class StubbedSession : public mtd::StubSession
1009 {
1010 public:
1011@@ -209,7 +218,7 @@
1012 mediator{__LINE__, shell, graphics_platform, graphics_changer,
1013 surface_pixel_formats, report,
1014 std::make_shared<mtd::NullEventSink>(),
1015- resource_cache, stub_screencast},
1016+ resource_cache, stub_screencast, &connector},
1017 stubbed_session{std::make_shared<StubbedSession>()},
1018 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}
1019 {
1020@@ -220,6 +229,7 @@
1021 .WillByDefault(WithArg<1>(Invoke(stubbed_session.get(), &StubbedSession::create_surface)));
1022 }
1023
1024+ MockConnector connector;
1025 std::shared_ptr<testing::NiceMock<mtd::MockShell>> const shell;
1026 std::shared_ptr<MockPlatform> const graphics_platform;
1027 std::shared_ptr<mf::DisplayChanger> const graphics_changer;
1028@@ -247,6 +257,42 @@
1029 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
1030 }
1031
1032+TEST_F(SessionMediatorTest, connect_calls_connect_handler)
1033+{
1034+ int connects_handled_count = 0;
1035+
1036+ mf::ConnectionContext const context =
1037+ {
1038+ [&](std::shared_ptr<mf::Session> const&) { ++connects_handled_count; },
1039+ nullptr
1040+ };
1041+
1042+ mf::SessionMediator mediator{
1043+ __LINE__,
1044+ shell,
1045+ graphics_platform,
1046+ graphics_changer,
1047+ surface_pixel_formats,
1048+ report,
1049+ std::make_shared<mtd::NullEventSink>(),
1050+ resource_cache,
1051+ stub_screencast,
1052+ context};
1053+
1054+ mp::ConnectParameters connect_parameters;
1055+ mp::Connection connection;
1056+
1057+ using namespace ::testing;
1058+
1059+ EXPECT_THAT(connects_handled_count, Eq(0));
1060+
1061+ mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
1062+ EXPECT_THAT(connects_handled_count, Eq(1));
1063+
1064+ mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
1065+ EXPECT_THAT(connects_handled_count, Eq(1));
1066+}
1067+
1068 TEST_F(SessionMediatorTest, calling_methods_before_connect_throws)
1069 {
1070 EXPECT_THROW({
1071@@ -373,7 +419,8 @@
1072 __LINE__, shell, graphics_platform, mock_display,
1073 surface_pixel_formats, report,
1074 std::make_shared<mtd::NullEventSink>(),
1075- resource_cache, std::make_shared<mtd::NullScreencast>());
1076+ resource_cache, std::make_shared<mtd::NullScreencast>(),
1077+ nullptr);
1078
1079 mp::ConnectParameters connect_parameters;
1080 mp::Connection connection;
1081@@ -597,7 +644,8 @@
1082 __LINE__, shell, graphics_platform, mock_display_selector,
1083 surface_pixel_formats, report,
1084 std::make_shared<mtd::NullEventSink>(), resource_cache,
1085- std::make_shared<mtd::NullScreencast>()};
1086+ std::make_shared<mtd::NullScreencast>(),
1087+ nullptr};
1088
1089 session_mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
1090
1091@@ -665,3 +713,52 @@
1092 EXPECT_EQ(stub_buffer.id().as_uint32_t(),
1093 protobuf_buffer.buffer_id());
1094 }
1095+
1096+TEST_F(SessionMediatorTest, client_socket_fd_calls_connector_client_socket_fd)
1097+{
1098+ const int fd_count = 1;
1099+ const int dummy_fd = __LINE__;
1100+
1101+ mp::ConnectParameters connect_parameters;
1102+ mp::Connection connection;
1103+
1104+ mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
1105+
1106+ ::mir::protobuf::SocketFDRequest request;
1107+ ::mir::protobuf::SocketFD response;
1108+ request.set_number(1);
1109+
1110+ using namespace ::testing;
1111+
1112+ EXPECT_CALL(connector, client_socket_fd(_)).Times(1).WillOnce(Return(dummy_fd));
1113+ mediator.new_fds_for_trusted_clients(nullptr, &request, &response, null_callback.get());
1114+
1115+ EXPECT_THAT(response.fd_size(), Eq(fd_count));
1116+ EXPECT_THAT(response.fd(0), Eq(dummy_fd));
1117+
1118+ mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
1119+}
1120+
1121+TEST_F(SessionMediatorTest, client_socket_fd_allocates_requested_number_of_fds)
1122+{
1123+ const int fd_count = 11;
1124+ const int dummy_fd = __LINE__;
1125+
1126+ mp::ConnectParameters connect_parameters;
1127+ mp::Connection connection;
1128+
1129+ mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
1130+
1131+ ::mir::protobuf::SocketFDRequest request;
1132+ ::mir::protobuf::SocketFD response;
1133+ request.set_number(fd_count);
1134+
1135+ using namespace ::testing;
1136+
1137+ EXPECT_CALL(connector, client_socket_fd(_)).Times(fd_count).WillRepeatedly(Return(dummy_fd));
1138+ mediator.new_fds_for_trusted_clients(nullptr, &request, &response, null_callback.get());
1139+
1140+ EXPECT_THAT(response.fd_size(), Eq(fd_count));
1141+
1142+ mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
1143+}
1144
1145=== modified file 'tests/unit-tests/frontend/test_session_mediator_android.cpp'
1146--- tests/unit-tests/frontend/test_session_mediator_android.cpp 2014-04-15 05:31:19 +0000
1147+++ tests/unit-tests/frontend/test_session_mediator_android.cpp 2014-05-07 14:18:03 +0000
1148@@ -61,7 +61,8 @@
1149 mediator{__LINE__, shell, graphics_platform, display_changer,
1150 surface_pixel_formats, report,
1151 std::make_shared<mtd::NullEventSink>(),
1152- resource_cache, std::make_shared<mtd::NullScreencast>()},
1153+ resource_cache, std::make_shared<mtd::NullScreencast>(),
1154+ nullptr},
1155 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}
1156 {
1157 }
1158
1159=== modified file 'tests/unit-tests/frontend/test_session_mediator_mesa.cpp'
1160--- tests/unit-tests/frontend/test_session_mediator_mesa.cpp 2014-04-15 05:31:19 +0000
1161+++ tests/unit-tests/frontend/test_session_mediator_mesa.cpp 2014-05-07 14:18:03 +0000
1162@@ -75,7 +75,8 @@
1163 mediator{__LINE__, shell, mock_platform, display_changer,
1164 surface_pixel_formats, report,
1165 std::make_shared<mtd::NullEventSink>(),
1166- resource_cache, std::make_shared<mtd::NullScreencast>()},
1167+ resource_cache, std::make_shared<mtd::NullScreencast>(),
1168+ nullptr},
1169 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}
1170 {
1171 }

Subscribers

People subscribed via source and target branches