Mir

Merge lp:~robertcarr/mir/add-session-listener into lp:~mir-team/mir/trunk

Proposed by Robert Carr
Status: Merged
Approved by: Robert Ancell
Approved revision: no longer in the source branch.
Merged at revision: 657
Proposed branch: lp:~robertcarr/mir/add-session-listener
Merge into: lp:~mir-team/mir/trunk
Diff against target: 441 lines (+192/-14)
9 files modified
include/server/mir/default_server_configuration.h (+3/-0)
include/server/mir/shell/null_session_listener.h (+48/-0)
include/server/mir/shell/session_listener.h (+48/-0)
include/server/mir/shell/session_manager.h (+5/-2)
src/server/default_server_configuration.cpp (+13/-1)
src/server/shell/session_manager.cpp (+9/-3)
tests/death-tests/test_application_manager_death.cpp (+2/-1)
tests/integration-tests/shell/test_session_manager.cpp (+7/-2)
tests/unit-tests/shell/test_session_manager.cpp (+57/-5)
To merge this branch: bzr merge lp:~robertcarr/mir/add-session-listener
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
PS Jenkins bot (community) continuous-integration Approve
Robert Ancell Approve
Review via email: mp+161910@code.launchpad.net

Commit message

Add a session listener, intended for the shell to maintain the Launcher model.

Description of the change

Add a session listener, intended for the shell to maintain the Launcher model.

To post a comment you must log in.
Revision history for this message
Robert Ancell (robert-ancell) wrote :

The appeared and vanished names sounds a bit dramatic but can't think off hand of something better :)

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

65 + virtual void application_appeared(std::shared_ptr<Session> const& session) = 0;
66 + virtual void application_vanished(std::shared_ptr<Session> const& session) = 0;

This is a *session* listener - so why is it expecting notifications about *applications*?

Maybe:

virtual void starting(std::shared_ptr<Session> const& session) = 0; and,
virtual void stopping(std::shared_ptr<Session> const& session) = 0?

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

I like these names, it says something about the fact that when the Session has been created (but before a Surface has been created) nothing has really "appeared", rather: the application is starting. Applied in r465

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/server/mir/default_server_configuration.h'
2--- include/server/mir/default_server_configuration.h 2013-04-26 12:21:57 +0000
3+++ include/server/mir/default_server_configuration.h 2013-05-01 20:55:28 +0000
4@@ -56,6 +56,7 @@
5 class FocusSetter;
6 class FocusSequence;
7 class PlacementStrategy;
8+class SessionListener;
9 class FocusController;
10 class SessionManager;
11 }
12@@ -157,6 +158,7 @@
13 virtual std::shared_ptr<shell::FocusSetter> the_shell_focus_setter();
14 virtual std::shared_ptr<shell::FocusSequence> the_shell_focus_sequence();
15 virtual std::shared_ptr<shell::PlacementStrategy> the_shell_placement_strategy();
16+ virtual std::shared_ptr<shell::SessionListener> the_shell_session_listener();
17 /** @} */
18
19 /** @name shell configuration - dependencies
20@@ -227,6 +229,7 @@
21 CachedPtr<shell::FocusSetter> shell_focus_setter;
22 CachedPtr<shell::FocusSequence> shell_focus_sequence;
23 CachedPtr<shell::PlacementStrategy> shell_placement_strategy;
24+ CachedPtr<shell::SessionListener> shell_session_listener;
25 CachedPtr<compositor::CompositingStrategy> compositing_strategy;
26 CachedPtr<compositor::OverlayRenderer> overlay_renderer;
27 CachedPtr<compositor::Compositor> compositor;
28
29=== added file 'include/server/mir/shell/null_session_listener.h'
30--- include/server/mir/shell/null_session_listener.h 1970-01-01 00:00:00 +0000
31+++ include/server/mir/shell/null_session_listener.h 2013-05-01 20:55:28 +0000
32@@ -0,0 +1,48 @@
33+/*
34+ * Copyright © 2012 Canonical Ltd.
35+ *
36+ * This program is free software: you can redistribute it and/or modify it
37+ * under the terms of the GNU General Public License version 3,
38+ * as published by the Free Software Foundation.
39+ *
40+ * This program is distributed in the hope that it will be useful,
41+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
42+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43+ * GNU General Public License for more details.
44+ *
45+ * You should have received a copy of the GNU General Public License
46+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
47+ *
48+ * Authored by: Robert Carr <robert.carr@canonical.com>
49+ */
50+
51+#ifndef MIR_SHELL_NULL_SESSION_LISTENER_H_
52+#define MIR_SHELL_NULL_SESSION_LISTENER_H_
53+
54+#include "mir/shell/session_listener.h"
55+
56+namespace mir
57+{
58+namespace shell
59+{
60+class Session;
61+
62+class NullSessionListener : public SessionListener
63+{
64+public:
65+ NullSessionListener() = default;
66+ virtual ~NullSessionListener() noexcept(true) = default;
67+
68+ void starting(std::shared_ptr<Session> const&) override {}
69+ void stopping(std::shared_ptr<Session> const&) override {}
70+
71+protected:
72+ NullSessionListener(const NullSessionListener&) = delete;
73+ NullSessionListener& operator=(const NullSessionListener&) = delete;
74+};
75+
76+}
77+}
78+
79+
80+#endif // MIR_SHELL_NULL_SESSION_LISTENER_H_
81
82=== added file 'include/server/mir/shell/session_listener.h'
83--- include/server/mir/shell/session_listener.h 1970-01-01 00:00:00 +0000
84+++ include/server/mir/shell/session_listener.h 2013-05-01 20:55:28 +0000
85@@ -0,0 +1,48 @@
86+/*
87+ * Copyright © 2012 Canonical Ltd.
88+ *
89+ * This program is free software: you can redistribute it and/or modify it
90+ * under the terms of the GNU General Public License version 3,
91+ * as published by the Free Software Foundation.
92+ *
93+ * This program is distributed in the hope that it will be useful,
94+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
95+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
96+ * GNU General Public License for more details.
97+ *
98+ * You should have received a copy of the GNU General Public License
99+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
100+ *
101+ * Authored by: Robert Carr <robert.carr@canonical.com>
102+ */
103+
104+#ifndef MIR_SHELL_SESSION_LISTENER_H_
105+#define MIR_SHELL_SESSION_LISTENER_H_
106+
107+#include <memory>
108+
109+namespace mir
110+{
111+namespace shell
112+{
113+class Session;
114+
115+class SessionListener
116+{
117+public:
118+ virtual void starting(std::shared_ptr<Session> const& session) = 0;
119+ virtual void stopping(std::shared_ptr<Session> const& session) = 0;
120+
121+protected:
122+ SessionListener() = default;
123+ virtual ~SessionListener() = default;
124+
125+ SessionListener(const SessionListener&) = delete;
126+ SessionListener& operator=(const SessionListener&) = delete;
127+};
128+
129+}
130+}
131+
132+
133+#endif // MIR_SHELL_SESSION_LISTENER_H_
134
135=== modified file 'include/server/mir/shell/session_manager.h'
136--- include/server/mir/shell/session_manager.h 2013-04-29 23:21:58 +0000
137+++ include/server/mir/shell/session_manager.h 2013-05-01 20:55:28 +0000
138@@ -41,8 +41,9 @@
139 class SessionContainer;
140 class FocusSequence;
141 class FocusSetter;
142+class Session;
143 class InputTargetListener;
144-class Session;
145+class SessionListener;
146
147 class SessionManager : public frontend::Shell, public shell::FocusController
148 {
149@@ -51,7 +52,8 @@
150 std::shared_ptr<SessionContainer> const& app_container,
151 std::shared_ptr<FocusSequence> const& focus_sequence,
152 std::shared_ptr<FocusSetter> const& focus_setter,
153- std::shared_ptr<InputTargetListener> const& input_target_listener);
154+ std::shared_ptr<InputTargetListener> const& input_target_listener,
155+ std::shared_ptr<SessionListener> const& session_listener);
156 virtual ~SessionManager();
157
158 virtual std::shared_ptr<frontend::Session> open_session(std::string const& name, std::shared_ptr<events::EventSink> const& sink);
159@@ -72,6 +74,7 @@
160 std::shared_ptr<FocusSequence> const focus_sequence;
161 std::shared_ptr<FocusSetter> const focus_setter;
162 std::shared_ptr<InputTargetListener> const input_target_listener;
163+ std::shared_ptr<SessionListener> const session_listener;
164
165 std::mutex mutex;
166 std::weak_ptr<Session> focus_application;
167
168=== modified file 'src/server/default_server_configuration.cpp'
169--- src/server/default_server_configuration.cpp 2013-04-26 12:21:57 +0000
170+++ src/server/default_server_configuration.cpp 2013-05-01 20:55:28 +0000
171@@ -39,6 +39,7 @@
172 #include "mir/shell/default_session_container.h"
173 #include "mir/shell/consuming_placement_strategy.h"
174 #include "mir/shell/organising_surface_factory.h"
175+#include "mir/shell/null_session_listener.h"
176 #include "mir/graphics/display.h"
177 #include "mir/graphics/gl_renderer.h"
178 #include "mir/graphics/renderer.h"
179@@ -344,6 +345,16 @@
180 });
181 }
182
183+std::shared_ptr<msh::SessionListener>
184+mir::DefaultServerConfiguration::the_shell_session_listener()
185+{
186+ return shell_session_listener(
187+ [this]
188+ {
189+ return std::make_shared<msh::NullSessionListener>();
190+ });
191+}
192+
193 std::shared_ptr<msh::SessionManager>
194 mir::DefaultServerConfiguration::the_session_manager()
195 {
196@@ -355,7 +366,8 @@
197 the_shell_session_container(),
198 the_shell_focus_sequence(),
199 the_shell_focus_setter(),
200- the_input_target_listener());
201+ the_input_target_listener(),
202+ the_shell_session_listener());
203 });
204 }
205
206
207=== modified file 'src/server/shell/session_manager.cpp'
208--- src/server/shell/session_manager.cpp 2013-04-29 23:21:58 +0000
209+++ src/server/shell/session_manager.cpp 2013-05-01 20:55:28 +0000
210@@ -25,6 +25,7 @@
211 #include "mir/shell/session.h"
212 #include "mir/shell/surface.h"
213 #include "mir/shell/input_target_listener.h"
214+#include "mir/shell/session_listener.h"
215
216 #include <memory>
217 #include <cassert>
218@@ -37,18 +38,21 @@
219 std::shared_ptr<msh::SessionContainer> const& container,
220 std::shared_ptr<msh::FocusSequence> const& sequence,
221 std::shared_ptr<msh::FocusSetter> const& focus_setter,
222- std::shared_ptr<msh::InputTargetListener> const& input_target_listener) :
223+ std::shared_ptr<msh::InputTargetListener> const& input_target_listener,
224+ std::shared_ptr<msh::SessionListener> const& session_listener) :
225 surface_factory(surface_factory),
226 app_container(container),
227 focus_sequence(sequence),
228 focus_setter(focus_setter),
229- input_target_listener(input_target_listener)
230+ input_target_listener(input_target_listener),
231+ session_listener(session_listener)
232 {
233 assert(surface_factory);
234 assert(sequence);
235 assert(container);
236 assert(focus_setter);
237 assert(input_target_listener);
238+ assert(session_listener);
239 }
240
241 msh::SessionManager::~SessionManager()
242@@ -59,11 +63,12 @@
243 std::string const& name,
244 std::shared_ptr<events::EventSink> const& sink)
245 {
246- auto new_session = std::make_shared<msh::ApplicationSession>(surface_factory, input_target_listener, name, sink);
247+ std::shared_ptr<msh::Session> new_session = std::make_shared<msh::ApplicationSession>(surface_factory, input_target_listener, name, sink);
248
249 app_container->insert_session(new_session);
250
251 input_target_listener->input_application_opened(new_session);
252+ session_listener->starting(new_session);
253
254 set_focus_to_locked(std::unique_lock<std::mutex>(mutex), new_session);
255
256@@ -88,6 +93,7 @@
257 auto shell_session = std::dynamic_pointer_cast<Session>(session);
258
259 input_target_listener->input_application_closed(shell_session);
260+ session_listener->stopping(shell_session);
261
262 app_container->remove_session(shell_session);
263
264
265=== modified file 'tests/death-tests/test_application_manager_death.cpp'
266--- tests/death-tests/test_application_manager_death.cpp 2013-04-24 05:22:20 +0000
267+++ tests/death-tests/test_application_manager_death.cpp 2013-05-01 20:55:28 +0000
268@@ -35,7 +35,8 @@
269 std::shared_ptr<msh::SessionContainer>(),
270 std::shared_ptr<msh::FocusSequence>(),
271 std::shared_ptr<msh::FocusSetter>(),
272- std::shared_ptr<msh::InputTargetListener>()),
273+ std::shared_ptr<msh::InputTargetListener>(),
274+ std::shared_ptr<msh::SessionListener>()),
275 ::testing::KilledBySignal(SIGABRT),
276 ".*");
277 }
278
279=== modified file 'tests/integration-tests/shell/test_session_manager.cpp'
280--- tests/integration-tests/shell/test_session_manager.cpp 2013-04-25 09:48:54 +0000
281+++ tests/integration-tests/shell/test_session_manager.cpp 2013-05-01 20:55:28 +0000
282@@ -22,6 +22,7 @@
283 #include "mir/shell/focus_setter.h"
284 #include "mir/shell/registration_order_focus_sequence.h"
285 #include "mir/shell/default_session_container.h"
286+#include "mir/shell/null_session_listener.h"
287 #include "mir/surfaces/buffer_bundle.h"
288 #include "mir/surfaces/surface.h"
289 #include "mir/compositor/buffer_swapper.h"
290@@ -53,13 +54,15 @@
291 mtd::MockFocusSetter focus_setter;
292 std::shared_ptr<mf::Session> new_session;
293 mtd::StubInputTargetListener input_target_listener;
294+ msh::NullSessionListener session_listener;
295
296 msh::SessionManager session_manager(
297 mt::fake_shared(surface_factory),
298 container,
299 mt::fake_shared(sequence),
300 mt::fake_shared(focus_setter),
301- mt::fake_shared(input_target_listener));
302+ mt::fake_shared(input_target_listener),
303+ mt::fake_shared(session_listener));
304
305 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);
306
307@@ -89,13 +92,15 @@
308 mtd::MockFocusSetter focus_setter;
309 std::shared_ptr<mf::Session> new_session;
310 mtd::StubInputTargetListener input_target_listener;
311+ msh::NullSessionListener session_listener;
312
313 msh::SessionManager session_manager(
314 mt::fake_shared(surface_factory),
315 container,
316 mt::fake_shared(sequence),
317 mt::fake_shared(focus_setter),
318- mt::fake_shared(input_target_listener));
319+ mt::fake_shared(input_target_listener),
320+ mt::fake_shared(session_listener));
321
322 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);
323
324
325=== modified file 'tests/unit-tests/shell/test_session_manager.cpp'
326--- tests/unit-tests/shell/test_session_manager.cpp 2013-04-29 23:21:58 +0000
327+++ tests/unit-tests/shell/test_session_manager.cpp 2013-05-01 20:55:28 +0000
328@@ -22,6 +22,9 @@
329 #include "mir/shell/default_session_container.h"
330 #include "mir/shell/session.h"
331 #include "mir/shell/input_target_listener.h"
332+#include "mir/shell/surface.h"
333+#include "mir/shell/session_listener.h"
334+#include "mir/shell/null_session_listener.h"
335 #include "mir/frontend/surface_creation_parameters.h"
336 #include "mir/surfaces/surface.h"
337 #include "mir/input/input_channel.h"
338@@ -35,8 +38,6 @@
339 #include "mir_test_doubles/stub_input_target_listener.h"
340 #include "mir_test_doubles/mock_input_target_listener.h"
341
342-#include "mir/shell/surface.h"
343-
344 #include <gmock/gmock.h>
345 #include <gtest/gtest.h>
346
347@@ -75,7 +76,8 @@
348 mt::fake_shared(container),
349 mt::fake_shared(focus_sequence),
350 mt::fake_shared(focus_setter),
351- mt::fake_shared(input_target_listener))
352+ mt::fake_shared(input_target_listener),
353+ mt::fake_shared(session_listener))
354 {
355 }
356
357@@ -85,6 +87,7 @@
358 MockFocusSequence focus_sequence;
359 testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub
360 mtd::StubInputTargetListener input_target_listener;
361+ msh::NullSessionListener session_listener;
362
363 msh::SessionManager session_manager;
364 };
365@@ -178,7 +181,8 @@
366 mt::fake_shared(container),
367 mt::fake_shared(focus_sequence),
368 mt::fake_shared(focus_setter),
369- mt::fake_shared(input_target_listener))
370+ mt::fake_shared(input_target_listener),
371+ mt::fake_shared(session_listener))
372 {
373 }
374
375@@ -188,13 +192,14 @@
376 testing::NiceMock<MockFocusSequence> focus_sequence;
377 testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub
378 mtd::MockInputTargetListener input_target_listener;
379+ msh::NullSessionListener session_listener;
380
381 msh::SessionManager session_manager;
382 };
383
384 }
385
386-TEST_F(SessionManagerInputTargetListenerSetup, listener_is_notified_of_session_and_surfacelifecycle)
387+TEST_F(SessionManagerInputTargetListenerSetup, input_listener_is_notified_of_session_and_surfacelifecycle)
388 {
389 using namespace ::testing;
390
391@@ -227,3 +232,50 @@
392 session_manager.close_session(session);
393 }
394 }
395+
396+namespace
397+{
398+
399+struct MockSessionListener : public msh::SessionListener
400+{
401+ virtual ~MockSessionListener() noexcept(true) {}
402+ MOCK_METHOD1(starting, void(std::shared_ptr<msh::Session> const&));
403+ MOCK_METHOD1(stopping, void(std::shared_ptr<msh::Session> const&));
404+};
405+
406+struct SessionManagerSessionTargetListenerSetup : public testing::Test
407+{
408+ SessionManagerSessionTargetListenerSetup()
409+ : session_manager(mt::fake_shared(surface_factory),
410+ mt::fake_shared(container),
411+ mt::fake_shared(focus_sequence),
412+ mt::fake_shared(focus_setter),
413+ mt::fake_shared(input_target_listener),
414+ mt::fake_shared(session_listener))
415+ {
416+ }
417+
418+ mtd::StubSurfaceBuilder surface_builder;
419+ mtd::MockSurfaceFactory surface_factory;
420+ testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub
421+ testing::NiceMock<MockFocusSequence> focus_sequence;
422+ testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub
423+ mtd::StubInputTargetListener input_target_listener;
424+ MockSessionListener session_listener;
425+
426+ msh::SessionManager session_manager;
427+};
428+}
429+
430+TEST_F(SessionManagerSessionTargetListenerSetup, session_listener_is_notified_of_lifecycle)
431+{
432+ using namespace ::testing;
433+
434+ EXPECT_CALL(session_listener, starting(_)).Times(1);
435+ EXPECT_CALL(session_listener, stopping(_)).Times(1);
436+
437+ EXPECT_CALL(focus_sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>())));
438+
439+ auto session = session_manager.open_session("XPlane", std::shared_ptr<me::EventSink>());
440+ session_manager.close_session(session);
441+}

Subscribers

People subscribed via source and target branches