Mir

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

Proposed by Alan Griffiths
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 1615
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: 1161 lines (+522/-41)
33 files modified
examples/render_surfaces.cpp (+1/-0)
include/client/mir_toolkit/mir_connection.h (+19/-0)
include/server/mir/frontend/connection_context.h (+52/-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 (+13/-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 (+5/-3)
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
Nick Dedekind (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Alexandros Frantzis (community) Approve
Alberto Aguirre (community) Approve
Review via email: mp+218629@code.launchpad.net

This proposal supersedes a proposal from 2014-05-02.

Commit message

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

Description of the change

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

This started as a "proof of concept" of an approach required by trust sessions - but has morphed into a pre-requisite during discussions.

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

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?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Looks good, just the following observations:

~~~
48 + * Copyright © 014 Canonical Ltd.
~~~

s/014/2014

~~~
206 + * \param [in] fds Array of FDs
~~~

Maybe document the fact that the array is only valid during the callback?

~~~
338 + catch (std::exception const&)
~~~
Shouldn't that be catch(...)?

review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Nits:

533 + const auto& fd = extract_fds_from(response);

auto const& (the file has both forms).

816 +

Unnecessary empty line.

81 + ConnectionContext() = delete;
82 + ConnectionContext(const ConnectionContext&) = default;
83 + ConnectionContext& operator=(const ConnectionContext&) = default;

Not needed, although I guess it doesn't hurt to be explicit, the alternative being having to remember all the implicit default/deletion rules. I am OK either way.

1087 + const int fd_count = 1;
1088 + const int dummy_fd = __LINE__;

1112 + const int fd_count = 11;
1113 + const int dummy_fd = __LINE__;

int const

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> 338 + catch (std::exception const&)
> ~~~
> Shouldn't that be catch(...)?

If we're seeing exceptions that are not derived from std::exception in the client API something is badly wrong. I think we should core and this gives us a decent chance of doing so.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

LGTM.
Tested with trust session branch and all seems well to this point.

review: Approve

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

Subscribers

People subscribed via source and target branches