Mir

Merge lp:~robertcarr/mir/send-input-to-clients into lp:~mir-team/mir/trunk

Proposed by Robert Carr
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 531
Proposed branch: lp:~robertcarr/mir/send-input-to-clients
Merge into: lp:~mir-team/mir/trunk
Diff against target: 2428 lines (+1326/-123)
59 files modified
examples/render_surfaces.cpp (+5/-1)
include/server/mir/default_server_configuration.h (+2/-0)
include/server/mir/input/input_manager.h (+8/-1)
include/server/mir/input/session_target.h (+45/-0)
include/server/mir/input/surface_target.h (+50/-0)
include/server/mir/shell/application_session.h (+4/-2)
include/server/mir/shell/focus_setter.h (+3/-6)
include/server/mir/shell/input_focus_selector.h (+52/-0)
include/server/mir/shell/session.h (+63/-0)
include/server/mir/shell/session_container.h (+3/-3)
include/server/mir/shell/single_visibility_focus_mechanism.h (+6/-7)
include/test/mir_test/wait_condition.h (+4/-0)
include/test/mir_test_doubles/mock_focus_setter.h (+1/-1)
include/test/mir_test_doubles/mock_input_focus_selector.h (+40/-0)
include/test/mir_test_doubles/mock_input_manager.h (+1/-0)
include/test/mir_test_doubles/mock_surface.h (+6/-0)
include/test/mir_test_doubles/stub_session_target.h (+44/-0)
include/test/mir_test_doubles/stub_surface_target.h (+59/-0)
include/test/mir_test_framework/testing_server_configuration.h (+1/-0)
src/server/default_server_configuration.cpp (+7/-2)
src/server/input/android/CMakeLists.txt (+2/-0)
src/server/input/android/android_input_application_handle.cpp (+42/-0)
src/server/input/android/android_input_application_handle.h (+58/-0)
src/server/input/android/android_input_manager.cpp (+28/-1)
src/server/input/android/android_input_manager.h (+7/-0)
src/server/input/android/android_input_window_handle.cpp (+74/-0)
src/server/input/android/android_input_window_handle.h (+59/-0)
src/server/input/android/default_android_input_configuration.cpp (+2/-0)
src/server/input/android/event_filter_dispatcher_policy.cpp (+1/-1)
src/server/input/dummy_input_manager.cpp (+3/-0)
src/server/shell/application_session.cpp (+8/-0)
src/server/shell/registration_order_focus_sequence.cpp (+1/-1)
src/server/shell/session_container.cpp (+1/-2)
src/server/shell/session_manager.cpp (+5/-3)
src/server/shell/single_visibility_focus_mechanism.cpp (+12/-4)
src/server/shell/surface.cpp (+19/-0)
src/server/shell/surface.h (+8/-1)
tests/acceptance-tests/CMakeLists.txt (+1/-1)
tests/acceptance-tests/test_focus_selection.cpp (+78/-25)
tests/behavior-tests/session_management_context.cpp (+1/-1)
tests/integration-tests/CMakeLists.txt (+1/-0)
tests/integration-tests/cucumber/test_session_management_context.cpp (+3/-19)
tests/integration-tests/frontend/CMakeLists.txt (+0/-1)
tests/integration-tests/input/android/test_android_input_manager.cpp (+118/-0)
tests/integration-tests/shell/CMakeLists.txt (+9/-0)
tests/integration-tests/shell/test_session_manager.cpp (+13/-21)
tests/mir_test_doubles/fake_event_hub.cpp (+3/-2)
tests/mir_test_framework/testing_server_options.cpp (+5/-0)
tests/unit-tests/input/android/CMakeLists.txt (+2/-0)
tests/unit-tests/input/android/test_android_input_application_handle.cpp (+58/-0)
tests/unit-tests/input/android/test_android_input_manager.cpp (+94/-2)
tests/unit-tests/input/android/test_android_input_window_handle.cpp (+89/-0)
tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp (+3/-1)
tests/unit-tests/shell/test_application_session.cpp (+36/-0)
tests/unit-tests/shell/test_registration_order_focus_sequence.cpp (+1/-1)
tests/unit-tests/shell/test_session_manager.cpp (+7/-6)
tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp (+51/-6)
tests/unit-tests/shell/test_surface.cpp (+18/-0)
tests/unit-tests/shell/test_the_session_container_implementation.cpp (+1/-1)
To merge this branch: bzr merge lp:~robertcarr/mir/send-input-to-clients
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Alan Griffiths Approve
Alexandros Frantzis (community) Approve
Review via email: mp+154221@code.launchpad.net

Commit message

Send input to clients through interfacing the InputManager and SessionManager

Description of the change

Send input to clients through interfacing the InputManager and SessionManager.

Two driving tests:
(acceptance )BespokeDisplayServerTestFixture.sessions_creating_surface_receive_focus

This test ensures the shell passes off focused surfaces to input by selecting the input focus. This is done through passing the InputFocusSelector (InputManager) to the SingleVisibilityFocusMechanism.

(integration) AndroidInputManagerDispatcherInterceptSetup.server_input_fd_of_focused_surface_is_sent_unfiltered_key_events

This test tests at the integration level that the reader policy, dispatcher, and dispatcher policy properly dispatch input to clients.

(unit) AndroidInputManagerFdSetup.set_input_focus is also a good entry point.

This tests that the focus is set correctly on the dispatcher.

To post a comment you must log in.
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 :

50 + virtual std::string name() const = 0;
51 +
...
59 + virtual int server_input_fd() const = 0;

These are not used by frontend. Therefore they don't belong on the frontend::Surface interface.

In principle, input should be defining interfaces that describe its own requirements. It should not injecting requirements into another part of the system nor relying on accidental similarity to what is needed elsewhere.

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

Also, FocusSelector should be defined in shell::, not in input::, since it's only used by shell::SingleVisibilityFocusMechanism

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

1. Moved focus selector
2. Defined mi::SurfaceTarget and mi::SessionTarget and use them for the interface. It's a little tricky as the focus mechanism, session container, etc...want to work in terms of msh::Session but create/close session, etc want to deal in terms of mf::Session...I couldn't find a clear structuring to make this work besides the dynamic_cast in SessionManager::set_focus_to...looking for improvements but I think some of it may be beyond the scope of this branch. At least these interfaces protect the input from continued session/shell changes.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
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 :

79 + virtual void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& session,
80 + std::shared_ptr<input::SurfaceTarget> const& surface) = 0;

A signature like this makes me wonder what should happen if session and surface are not associated. (Or if there is a requirement that surface belongs to session why both need to be supplied.)

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

122 +
123 + virtual std::string name() = 0;

surely this can be const?

~~~~

529 +#include <gtest/gtest.h>

Not needed

~~~~

922 -
923 +

Adding pointless whitespace.

~~~~

1531 === modified file 'tests/integration-tests/frontend/test_session_manager.cpp'

This really ought to be

tests/integration-tests/*shell*/test_session_manager.cpp

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

This might cause a cascade of fixes - if so, it belongs to another cleanup MP...

121 + virtual ~SessionTarget() {}

Shouldn't that be virtual "~SessionTarget() = default" (there is a semantic difference - the latter is noexcept).

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

>> surely this can be const?
r557

>>529 +#include <gtest/gtest.h>
>>
>>Not needed
r558!

>> 922 -
>> 923 +

r559

>>This really ought to be

>>tests/integration-tests/*shell*/test_session_manager.cpp
r560

>> This might cause a cascade of fixes - if so, it belongs to another cleanup MP...

It does cause a cascade so lets fix it next.

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 :

Concerns addressed - but has merge conflicts.

Abstaining so to avoid blocking

review: Abstain
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
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: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Dammit. My copy of trunk needed updating

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

Merged trunk.

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

We should not be using the system clock - our own timesource can be mocked to facilitate testing of time dependent scenarios.

But that can be fixed later. Let's land the rest.

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

> We should not be using the system clock - our own timesource can be mocked to
> facilitate testing of time dependent scenarios.
>

And

991 +// mInfo->touchableRegion = touchable_region;
...
998 +// mInfo->layer = props.layer;

Comments shouldn't contain code

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

Fixed the comments

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

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 2013-03-21 03:32:59 +0000
3+++ examples/render_surfaces.cpp 2013-03-22 17:46:22 +0000
4@@ -47,9 +47,9 @@
5 namespace mc = mir::compositor;
6 namespace ms = mir::surfaces;
7 namespace mf = mir::frontend;
8+namespace mi = mir::input;
9 namespace geom = mir::geometry;
10 namespace mt = mir::tools;
11-namespace mi = mir::input;
12
13 namespace
14 {
15@@ -194,6 +194,10 @@
16 {
17 return std::shared_ptr<mi::InputChannel>();
18 }
19+ void set_input_focus_to(std::shared_ptr<mi::SessionTarget> const& /* session */,
20+ std::shared_ptr<mi::SurfaceTarget> const& /* surface */)
21+ {
22+ }
23 };
24
25 class RenderSurfacesCompositingStrategy : public mc::DefaultCompositingStrategy
26
27=== modified file 'include/server/mir/default_server_configuration.h'
28--- include/server/mir/default_server_configuration.h 2013-03-22 03:33:00 +0000
29+++ include/server/mir/default_server_configuration.h 2013-03-22 17:46:22 +0000
30@@ -52,6 +52,7 @@
31 class SurfaceFactory;
32 class SurfaceSource;
33 class SurfaceBuilder;
34+class InputFocusSelector;
35 }
36 namespace surfaces
37 {
38@@ -113,6 +114,7 @@
39
40 virtual std::initializer_list<std::shared_ptr<input::EventFilter> const> the_event_filters();
41 virtual std::shared_ptr<input::InputManager> the_input_manager();
42+ virtual std::shared_ptr<shell::InputFocusSelector> the_input_focus_selector();
43
44 virtual std::shared_ptr<shell::SurfaceBuilder> the_surface_builder();
45
46
47=== modified file 'include/server/mir/input/input_manager.h'
48--- include/server/mir/input/input_manager.h 2013-03-21 03:32:59 +0000
49+++ include/server/mir/input/input_manager.h 2013-03-22 17:46:22 +0000
50@@ -21,6 +21,7 @@
51 #define MIR_INPUT_INPUT_MANAGER_H_
52
53 #include "mir/input/input_channel_factory.h"
54+#include "mir/shell/input_focus_selector.h"
55
56 #include <memory>
57
58@@ -30,12 +31,15 @@
59 {
60 class ViewableArea;
61 }
62+
63 namespace input
64 {
65 class EventFilter;
66 class InputChannel;
67+class SessionTarget;
68+class SurfaceTarget;
69
70-class InputManager : public InputChannelFactory
71+class InputManager : public InputChannelFactory, public shell::InputFocusSelector
72 {
73 public:
74 virtual void start() = 0;
75@@ -43,6 +47,9 @@
76
77 virtual std::shared_ptr<InputChannel> make_input_channel() = 0;
78
79+ virtual void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& session,
80+ std::shared_ptr<input::SurfaceTarget> const& surface) = 0;
81+
82 protected:
83 InputManager() {};
84 virtual ~InputManager() {}
85
86=== added file 'include/server/mir/input/session_target.h'
87--- include/server/mir/input/session_target.h 1970-01-01 00:00:00 +0000
88+++ include/server/mir/input/session_target.h 2013-03-22 17:46:22 +0000
89@@ -0,0 +1,45 @@
90+/*
91+ * Copyright © 2013 Canonical Ltd.
92+ *
93+ * This program is free software: you can redistribute it and/or modify it
94+ * under the terms of the GNU Lesser General Public License version 3,
95+ * as published by the Free Software Foundation.
96+ *
97+ * This program is distributed in the hope that it will be useful,
98+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
99+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
100+ * GNU General Public License for more details.
101+ *
102+ * You should have received a copy of the GNU Lesser General Public License
103+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
104+ *
105+ * Authored by: Robert Carr <robert.carr@canonical.com>
106+ */
107+
108+#ifndef MIR_INPUT_SESSION_TARGET_H_
109+#define MIR_INPUT_SESSION_TARGET_H_
110+
111+#include <string>
112+
113+namespace mir
114+{
115+namespace input
116+{
117+
118+class SessionTarget
119+{
120+public:
121+ virtual ~SessionTarget() {}
122+
123+ virtual std::string name() const = 0;
124+
125+protected:
126+ SessionTarget() = default;
127+ SessionTarget(SessionTarget const&) = delete;
128+ SessionTarget& operator=(SessionTarget const&) = delete;
129+};
130+
131+}
132+} // namespace mir
133+
134+#endif // MIR_INPUT_SESSION_TARGET_H_
135
136=== added file 'include/server/mir/input/surface_target.h'
137--- include/server/mir/input/surface_target.h 1970-01-01 00:00:00 +0000
138+++ include/server/mir/input/surface_target.h 2013-03-22 17:46:22 +0000
139@@ -0,0 +1,50 @@
140+/*
141+ * Copyright © 2013 Canonical Ltd.
142+ *
143+ * This program is free software: you can redistribute it and/or modify it
144+ * under the terms of the GNU Lesser General Public License version 3,
145+ * as published by the Free Software Foundation.
146+ *
147+ * This program is distributed in the hope that it will be useful,
148+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
149+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
150+ * GNU General Public License for more details.
151+ *
152+ * You should have received a copy of the GNU Lesser General Public License
153+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
154+ *
155+ * Authored by: Robert Carr <robert.carr@canonical.com>
156+ */
157+
158+#ifndef MIR_INPUT_SURFACE_TARGET_H_
159+#define MIR_INPUT_SURFACE_TARGET_H_
160+
161+#include "mir/geometry/size.h"
162+
163+#include <string>
164+
165+namespace mir
166+{
167+namespace input
168+{
169+
170+class SurfaceTarget
171+{
172+public:
173+ virtual ~SurfaceTarget() {}
174+
175+ virtual geometry::Size size() const = 0;
176+ virtual std::string name() const = 0;
177+
178+ virtual int server_input_fd() const = 0;
179+
180+protected:
181+ SurfaceTarget() = default;
182+ SurfaceTarget(SurfaceTarget const&) = delete;
183+ SurfaceTarget& operator=(SurfaceTarget const&) = delete;
184+};
185+
186+}
187+} // namespace mir
188+
189+#endif // MIR_INPUT_SURFACE_TARGET_H_
190
191=== modified file 'include/server/mir/shell/application_session.h'
192--- include/server/mir/shell/application_session.h 2013-03-22 03:33:00 +0000
193+++ include/server/mir/shell/application_session.h 2013-03-22 17:46:22 +0000
194@@ -19,7 +19,7 @@
195 #ifndef MIR_SHELL_APPLICATION_SESSION_H_
196 #define MIR_SHELL_APPLICATION_SESSION_H_
197
198-#include "mir/frontend/session.h"
199+#include "mir/shell/session.h"
200
201 #include <map>
202
203@@ -31,7 +31,7 @@
204 class SurfaceFactory;
205 class Surface;
206
207-class ApplicationSession : public frontend::Session
208+class ApplicationSession : public Session
209 {
210 public:
211 explicit ApplicationSession(std::shared_ptr<SurfaceFactory> const& surface_factory, std::string const& session_name);
212@@ -41,6 +41,8 @@
213 void destroy_surface(frontend::SurfaceId surface);
214 std::shared_ptr<frontend::Surface> get_surface(frontend::SurfaceId surface) const;
215
216+ std::shared_ptr<Surface> default_surface() const;
217+
218 std::string name() const;
219
220 void shutdown();
221
222=== modified file 'include/server/mir/shell/focus_setter.h'
223--- include/server/mir/shell/focus_setter.h 2013-03-21 03:32:59 +0000
224+++ include/server/mir/shell/focus_setter.h 2013-03-22 17:46:22 +0000
225@@ -23,20 +23,17 @@
226
227 namespace mir
228 {
229-namespace frontend
230+
231+namespace shell
232 {
233 class Session;
234-}
235-
236-namespace shell
237-{
238
239 class FocusSetter
240 {
241 public:
242 virtual ~FocusSetter() {}
243
244- virtual void set_focus_to(std::shared_ptr<frontend::Session> const& new_focus) = 0;
245+ virtual void set_focus_to(std::shared_ptr<shell::Session> const& new_focus) = 0;
246
247 protected:
248 FocusSetter() = default;
249
250=== added file 'include/server/mir/shell/input_focus_selector.h'
251--- include/server/mir/shell/input_focus_selector.h 1970-01-01 00:00:00 +0000
252+++ include/server/mir/shell/input_focus_selector.h 2013-03-22 17:46:22 +0000
253@@ -0,0 +1,52 @@
254+/*
255+ * Copyright © 2013 Canonical Ltd.
256+ *
257+ * This program is free software: you can redistribute it and/or modify it
258+ * under the terms of the GNU Lesser General Public License version 3,
259+ * as published by the Free Software Foundation.
260+ *
261+ * This program is distributed in the hope that it will be useful,
262+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
263+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
264+ * GNU General Public License for more details.
265+ *
266+ * You should have received a copy of the GNU Lesser General Public License
267+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
268+ *
269+ * Authored by: Robert Carr <robert.carr@canonical.com>
270+ */
271+
272+#ifndef MIR_SHELL_INPUT_FOCUS_SELECTOR_H_
273+#define MIR_SHELL_INPUT_FOCUS_SELECTOR_H_
274+
275+#include <memory>
276+
277+namespace mir
278+{
279+namespace input
280+{
281+class SessionTarget;
282+class SurfaceTarget;
283+}
284+
285+namespace shell
286+{
287+
288+class InputFocusSelector
289+{
290+public:
291+ virtual ~InputFocusSelector() {}
292+
293+ virtual void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& focus_application,
294+ std::shared_ptr<input::SurfaceTarget> const& focus_surface) = 0;
295+
296+protected:
297+ InputFocusSelector() = default;
298+ InputFocusSelector(InputFocusSelector const&) = delete;
299+ InputFocusSelector& operator=(InputFocusSelector const&) = delete;
300+};
301+
302+}
303+} // namespace mir
304+
305+#endif // MIR_SHELL_INPUT_FOCUS_SELECTOR_H_
306
307=== added file 'include/server/mir/shell/session.h'
308--- include/server/mir/shell/session.h 1970-01-01 00:00:00 +0000
309+++ include/server/mir/shell/session.h 2013-03-22 17:46:22 +0000
310@@ -0,0 +1,63 @@
311+/*
312+ * Copyright © 2012 Canonical Ltd.
313+ *
314+ * This program is free software: you can redistribute it and/or modify it
315+ * under the terms of the GNU Lesser General Public License version 3,
316+ * as published by the Free Software Foundation.
317+ *
318+ * This program is distributed in the hope that it will be useful,
319+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
320+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
321+ * GNU General Public License for more details.
322+ *
323+ * You should have received a copy of the GNU Lesser General Public License
324+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
325+ *
326+ * Authored By: Robert Carr <racarr@canonical.com>
327+ */
328+
329+#ifndef MIR_SHELL_SESSION_H_
330+#define MIR_SHELL_SESSION_H_
331+
332+#include "mir/frontend/session.h"
333+#include "mir/input/session_target.h"
334+
335+#include <mutex>
336+#include <atomic>
337+#include <memory>
338+#include <string>
339+
340+namespace mir
341+{
342+
343+namespace shell
344+{
345+class Surface;
346+
347+class Session : public frontend::Session, public input::SessionTarget
348+{
349+public:
350+ virtual ~Session() {}
351+
352+ virtual frontend::SurfaceId create_surface(frontend::SurfaceCreationParameters const& params) = 0;
353+ virtual void destroy_surface(frontend::SurfaceId surface) = 0;
354+ virtual std::shared_ptr<frontend::Surface> get_surface(frontend::SurfaceId surface) const = 0;
355+
356+ virtual std::string name() const = 0;
357+ virtual void shutdown() = 0;
358+
359+ virtual void hide() = 0;
360+ virtual void show() = 0;
361+
362+ virtual std::shared_ptr<Surface> default_surface() const = 0;
363+
364+protected:
365+ Session() = default;
366+ Session(Session const&) = delete;
367+ Session& operator=(Session const&) = delete;
368+};
369+
370+}
371+}
372+
373+#endif // MIR_SHELL_SESSION_H_
374
375=== renamed file 'include/server/mir/frontend/session_container.h' => 'include/server/mir/shell/session_container.h'
376--- include/server/mir/frontend/session_container.h 2013-03-21 03:32:59 +0000
377+++ include/server/mir/shell/session_container.h 2013-03-22 17:46:22 +0000
378@@ -16,8 +16,8 @@
379 * Authored by: Robert Carr <robert.carr@canonical.com>
380 */
381
382-#ifndef FRONTEND_SESSION_CONTAINER_H_
383-#define FRONTEND_SESSION_CONTAINER_H_
384+#ifndef MIR_SHELL_SESSION_CONTAINER_H_
385+#define MIR_SHELL_SESSION_CONTAINER_H_
386
387 #include <vector>
388 #include <memory>
389@@ -56,4 +56,4 @@
390 }
391
392
393-#endif // FRONTEND_SESSION_CONTAINER_H_
394+#endif // MIR_SHELL_SESSION_CONTAINER_H_
395
396=== modified file 'include/server/mir/shell/single_visibility_focus_mechanism.h'
397--- include/server/mir/shell/single_visibility_focus_mechanism.h 2013-03-21 03:32:59 +0000
398+++ include/server/mir/shell/single_visibility_focus_mechanism.h 2013-03-22 17:46:22 +0000
399@@ -24,28 +24,27 @@
400
401 namespace mir
402 {
403-namespace frontend
404-{
405-class Session;
406-}
407
408 namespace shell
409 {
410 class SessionContainer;
411+class InputFocusSelector;
412
413 class SingleVisibilityFocusMechanism : public FocusSetter
414 {
415 public:
416- explicit SingleVisibilityFocusMechanism(std::shared_ptr<SessionContainer> const& app_container);
417+ explicit SingleVisibilityFocusMechanism(std::shared_ptr<SessionContainer> const& app_container,
418+ std::shared_ptr<shell::InputFocusSelector> const& input_selector);
419 virtual ~SingleVisibilityFocusMechanism() {}
420
421- void set_focus_to(std::shared_ptr<frontend::Session> const& new_focus);
422+ void set_focus_to(std::shared_ptr<shell::Session> const& new_focus);
423
424 protected:
425 SingleVisibilityFocusMechanism(const SingleVisibilityFocusMechanism&) = delete;
426 SingleVisibilityFocusMechanism& operator=(const SingleVisibilityFocusMechanism&) = delete;
427 private:
428- std::shared_ptr<SessionContainer> app_container;
429+ std::shared_ptr<SessionContainer> const app_container;
430+ std::shared_ptr<shell::InputFocusSelector> const input_selector;
431 };
432
433 }
434
435=== modified file 'include/test/mir_test/wait_condition.h'
436--- include/test/mir_test/wait_condition.h 2013-03-13 04:54:15 +0000
437+++ include/test/mir_test/wait_condition.h 2013-03-22 17:46:22 +0000
438@@ -55,6 +55,10 @@
439 wait_condition->wake_up_everyone();
440 return false;
441 }
442+ACTION_P(WakeUp, wait_condition)
443+{
444+ wait_condition->wake_up_everyone();
445+}
446 }
447
448 #endif // MIR_TEST_WAIT_CONDITION_H_
449
450=== modified file 'include/test/mir_test_doubles/mock_focus_setter.h'
451--- include/test/mir_test_doubles/mock_focus_setter.h 2013-03-15 23:15:45 +0000
452+++ include/test/mir_test_doubles/mock_focus_setter.h 2013-03-22 17:46:22 +0000
453@@ -32,7 +32,7 @@
454
455 struct MockFocusSetter : public shell::FocusSetter
456 {
457- MOCK_METHOD1(set_focus_to, void(std::shared_ptr<frontend::Session> const&));
458+ MOCK_METHOD1(set_focus_to, void(std::shared_ptr<shell::Session> const&));
459 };
460
461 }
462
463=== added file 'include/test/mir_test_doubles/mock_input_focus_selector.h'
464--- include/test/mir_test_doubles/mock_input_focus_selector.h 1970-01-01 00:00:00 +0000
465+++ include/test/mir_test_doubles/mock_input_focus_selector.h 2013-03-22 17:46:22 +0000
466@@ -0,0 +1,40 @@
467+/*
468+ * Copyright © 2013 Canonical Ltd.
469+ *
470+ * This program is free software: you can redistribute it and/or modify it
471+ * under the terms of the GNU Lesser General Public License version 3,
472+ * as published by the Free Software Foundation.
473+ *
474+ * This program is distributed in the hope that it will be useful,
475+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
476+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
477+ * GNU General Public License for more details.
478+ *
479+ * You should have received a copy of the GNU Lesser General Public License
480+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
481+ *
482+ * Authored by: Robert Carr <robert.carr@canonical.com>
483+ */
484+
485+#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_FOCUS_SELECTOR_H_
486+#define MIR_TEST_DOUBLES_MOCK_INPUT_FOCUS_SELECTOR_H_
487+
488+#include "mir/shell/input_focus_selector.h"
489+
490+namespace mir
491+{
492+namespace test
493+{
494+namespace doubles
495+{
496+
497+struct MockInputFocusSelector : public shell::InputFocusSelector
498+{
499+ MOCK_METHOD2(set_input_focus_to, void(std::shared_ptr<input::SessionTarget> const&, std::shared_ptr<input::SurfaceTarget> const&));
500+};
501+
502+}
503+}
504+} // namespace mir
505+
506+#endif // MIR_TEST_DOUBLES_MOCK_INPUT_FOCUS_SELECTOR_H_
507
508=== modified file 'include/test/mir_test_doubles/mock_input_manager.h'
509--- include/test/mir_test_doubles/mock_input_manager.h 2013-03-21 03:32:59 +0000
510+++ include/test/mir_test_doubles/mock_input_manager.h 2013-03-22 17:46:22 +0000
511@@ -37,6 +37,7 @@
512 MOCK_METHOD0(stop, void());
513
514 MOCK_METHOD0(make_input_channel, std::shared_ptr<input::InputChannel>());
515+ MOCK_METHOD2(set_input_focus_to, void(std::shared_ptr<input::SessionTarget> const& session, std::shared_ptr<input::SurfaceTarget> const& surface));
516 };
517
518 }
519
520=== modified file 'include/test/mir_test_doubles/mock_surface.h'
521--- include/test/mir_test_doubles/mock_surface.h 2013-03-21 03:32:59 +0000
522+++ include/test/mir_test_doubles/mock_surface.h 2013-03-22 17:46:22 +0000
523@@ -21,6 +21,10 @@
524
525 #include "src/server/shell/surface.h"
526
527+#include "mir/frontend/surface_creation_parameters.h"
528+
529+#include <gmock/gmock.h>
530+
531 #include <memory>
532
533 namespace mir
534@@ -43,12 +47,14 @@
535 MOCK_METHOD0(shutdown, void());
536 MOCK_METHOD0(advance_client_buffer, void());
537
538+ MOCK_CONST_METHOD0(name, std::string ());
539 MOCK_CONST_METHOD0(size, geometry::Size ());
540 MOCK_CONST_METHOD0(pixel_format, geometry::PixelFormat ());
541 MOCK_CONST_METHOD0(client_buffer, std::shared_ptr<compositor::Buffer> ());
542
543 MOCK_CONST_METHOD0(supports_input, bool());
544 MOCK_CONST_METHOD0(client_input_fd, int());
545+ MOCK_CONST_METHOD0(server_input_fd, int());
546
547 MOCK_METHOD2(configure, int(MirSurfaceAttrib, int));
548 };
549
550=== added file 'include/test/mir_test_doubles/stub_session_target.h'
551--- include/test/mir_test_doubles/stub_session_target.h 1970-01-01 00:00:00 +0000
552+++ include/test/mir_test_doubles/stub_session_target.h 2013-03-22 17:46:22 +0000
553@@ -0,0 +1,44 @@
554+/*
555+ * Copyright © 2013 Canonical Ltd.
556+ *
557+ * This program is free software: you can redistribute it and/or modify it
558+ * under the terms of the GNU Lesser General Public License version 3,
559+ * as published by the Free Software Foundation.
560+ *
561+ * This program is distributed in the hope that it will be useful,
562+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
563+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
564+ * GNU General Public License for more details.
565+ *
566+ * You should have received a copy of the GNU Lesser General Public License
567+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
568+ *
569+ * Authored by: Robert Carr <robert.carr@canonical.com>
570+ */
571+
572+#ifndef MIR_TEST_DOUBLES_STUB_SESSION_TARGET_H_
573+#define MIR_TEST_DOUBLES_STUB_SESSION_TARGET_H_
574+
575+#include "mir/input/session_target.h"
576+
577+namespace mir
578+{
579+namespace test
580+{
581+namespace doubles
582+{
583+
584+struct StubSessionTarget : public input::SessionTarget
585+{
586+ std::string name() const override
587+ {
588+ return std::string();
589+ }
590+};
591+
592+}
593+}
594+} // namespace mir
595+
596+#endif // MIR_TEST_DOUBLES_STUB_SESSION_TARGET_H_
597+
598
599=== added file 'include/test/mir_test_doubles/stub_surface_target.h'
600--- include/test/mir_test_doubles/stub_surface_target.h 1970-01-01 00:00:00 +0000
601+++ include/test/mir_test_doubles/stub_surface_target.h 2013-03-22 17:46:22 +0000
602@@ -0,0 +1,59 @@
603+/*
604+ * Copyright © 2013 Canonical Ltd.
605+ *
606+ * This program is free software: you can redistribute it and/or modify it
607+ * under the terms of the GNU Lesser General Public License version 3,
608+ * as published by the Free Software Foundation.
609+ *
610+ * This program is distributed in the hope that it will be useful,
611+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
612+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
613+ * GNU General Public License for more details.
614+ *
615+ * You should have received a copy of the GNU Lesser General Public License
616+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
617+ *
618+ * Authored by: Robert Carr <robert.carr@canonical.com>
619+ */
620+
621+#ifndef MIR_TEST_DOUBLES_STUB_SURFACE_TARGET_H_
622+#define MIR_TEST_DOUBLES_STUB_SURFACE_TARGET_H_
623+
624+#include "mir/input/surface_target.h"
625+
626+namespace mir
627+{
628+namespace test
629+{
630+namespace doubles
631+{
632+
633+struct StubSurfaceTarget : public input::SurfaceTarget
634+{
635+ StubSurfaceTarget(int fd)
636+ : input_fd(fd)
637+ {
638+ }
639+
640+ int server_input_fd() const override
641+ {
642+ return input_fd;
643+ }
644+ geometry::Size size() const override
645+ {
646+ return geometry::Size();
647+ }
648+ std::string name() const override
649+ {
650+ return std::string();
651+ }
652+
653+ int input_fd;
654+};
655+
656+}
657+}
658+} // namespace mir
659+
660+#endif // MIR_TEST_DOUBLES_STUB_SURFACE_TARGET_H_
661+
662
663=== modified file 'include/test/mir_test_framework/testing_server_configuration.h'
664--- include/test/mir_test_framework/testing_server_configuration.h 2013-03-13 04:54:15 +0000
665+++ include/test/mir_test_framework/testing_server_configuration.h 2013-03-22 17:46:22 +0000
666@@ -53,6 +53,7 @@
667 virtual std::string the_socket_file() const;
668 using DefaultServerConfiguration::the_options;
669
670+
671 private:
672 std::shared_ptr<graphics::Platform> graphics_platform;
673 };
674
675=== modified file 'src/server/default_server_configuration.cpp'
676--- src/server/default_server_configuration.cpp 2013-03-22 17:08:01 +0000
677+++ src/server/default_server_configuration.cpp 2013-03-22 17:46:22 +0000
678@@ -33,7 +33,7 @@
679 #include "mir/shell/session_manager.h"
680 #include "mir/shell/registration_order_focus_sequence.h"
681 #include "mir/shell/single_visibility_focus_mechanism.h"
682-#include "mir/frontend/session_container.h"
683+#include "mir/shell/session_container.h"
684 #include "mir/shell/consuming_placement_strategy.h"
685 #include "mir/shell/organising_surface_factory.h"
686 #include "mir/graphics/display.h"
687@@ -266,7 +266,7 @@
688 [this]() -> std::shared_ptr<msh::SessionManager>
689 {
690 auto session_container = std::make_shared<msh::SessionContainer>();
691- auto focus_mechanism = std::make_shared<msh::SingleVisibilityFocusMechanism>(session_container);
692+ auto focus_mechanism = std::make_shared<msh::SingleVisibilityFocusMechanism>(session_container, the_input_focus_selector());
693 auto focus_selection_strategy = std::make_shared<msh::RegistrationOrderFocusSequence>(session_container);
694
695 auto placement_strategy = std::make_shared<msh::ConsumingPlacementStrategy>(the_display());
696@@ -455,3 +455,8 @@
697 {
698 return the_input_manager();
699 }
700+
701+std::shared_ptr<msh::InputFocusSelector> mir::DefaultServerConfiguration::the_input_focus_selector()
702+{
703+ return the_input_manager();
704+}
705
706=== modified file 'src/server/input/android/CMakeLists.txt'
707--- src/server/input/android/CMakeLists.txt 2013-03-21 03:32:59 +0000
708+++ src/server/input/android/CMakeLists.txt 2013-03-22 17:46:22 +0000
709@@ -8,6 +8,8 @@
710 ${CMAKE_CURRENT_SOURCE_DIR}/rudimentary_input_reader_policy.cpp
711 ${CMAKE_CURRENT_SOURCE_DIR}/event_filter_dispatcher_policy.cpp
712 ${CMAKE_CURRENT_SOURCE_DIR}/default_android_input_configuration.cpp
713+ ${CMAKE_CURRENT_SOURCE_DIR}/android_input_application_handle.cpp
714+ ${CMAKE_CURRENT_SOURCE_DIR}/android_input_window_handle.cpp
715 )
716
717 set(
718
719=== added file 'src/server/input/android/android_input_application_handle.cpp'
720--- src/server/input/android/android_input_application_handle.cpp 1970-01-01 00:00:00 +0000
721+++ src/server/input/android/android_input_application_handle.cpp 2013-03-22 17:46:22 +0000
722@@ -0,0 +1,42 @@
723+/*
724+ * Copyright © 2013 Canonical Ltd.
725+ *
726+ * This program is free software: you can redistribute it and/or modify
727+ * it under the terms of the GNU General Public License version 3 as
728+ * published by the Free Software Foundation.
729+ *
730+ * This program is distributed in the hope that it will be useful,
731+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
732+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
733+ * GNU General Public License for more details.
734+ *
735+ * You should have received a copy of the GNU General Public License
736+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
737+ *
738+ * Authored by: Robert Carr <robert.carr@canonical.com>
739+ */
740+
741+#include "android_input_application_handle.h"
742+
743+#include "mir/input/session_target.h"
744+
745+#include <limits.h>
746+
747+namespace mi = mir::input;
748+namespace mia = mi::android;
749+
750+mia::InputApplicationHandle::InputApplicationHandle(std::shared_ptr<mi::SessionTarget> const& session)
751+ : session(session)
752+{
753+ updateInfo();
754+}
755+
756+bool mia::InputApplicationHandle::updateInfo()
757+{
758+ if (mInfo == NULL)
759+ mInfo = new droidinput::InputApplicationInfo;
760+ mInfo->dispatchingTimeout = INT_MAX;
761+ mInfo->name = droidinput::String8(session->name().c_str());
762+
763+ return true;
764+}
765
766=== added file 'src/server/input/android/android_input_application_handle.h'
767--- src/server/input/android/android_input_application_handle.h 1970-01-01 00:00:00 +0000
768+++ src/server/input/android/android_input_application_handle.h 2013-03-22 17:46:22 +0000
769@@ -0,0 +1,58 @@
770+/*
771+ * Copyright © 2013 Canonical Ltd.
772+ *
773+ * This program is free software: you can redistribute it and/or modify
774+ * it under the terms of the GNU General Public License version 3 as
775+ * published by the Free Software Foundation.
776+ *
777+ * This program is distributed in the hope that it will be useful,
778+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
779+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
780+ * GNU General Public License for more details.
781+ *
782+ * You should have received a copy of the GNU General Public License
783+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
784+ *
785+ * Authored by: Robert Carr <robert.carr@canonical.com>
786+ */
787+
788+#ifndef MIR_INPUT_ANDROID_INPUT_APPLICATION_HANDLE_H_
789+#define MIR_INPUT_ANDROID_INPUT_APPLICATION_HANDLE_H_
790+
791+#include <InputApplication.h>
792+
793+#include <memory>
794+
795+namespace droidinput = android;
796+
797+namespace mir
798+{
799+
800+namespace input
801+{
802+class SessionTarget;
803+
804+namespace android
805+{
806+
807+class InputApplicationHandle : public droidinput::InputApplicationHandle
808+{
809+public:
810+ InputApplicationHandle(std::shared_ptr<input::SessionTarget> const& surface);
811+ ~InputApplicationHandle() {}
812+
813+ bool updateInfo();
814+
815+protected:
816+ InputApplicationHandle(InputApplicationHandle const&) = delete;
817+ InputApplicationHandle& operator=(InputApplicationHandle const&) = delete;
818+
819+private:
820+ std::shared_ptr<input::SessionTarget> session;
821+};
822+
823+}
824+}
825+} // namespace mir
826+
827+#endif // MIR_INPUT_ANDROID_INPUT_APPLICATION_HANDLE_H_
828
829=== modified file 'src/server/input/android/android_input_manager.cpp'
830--- src/server/input/android/android_input_manager.cpp 2013-03-21 03:32:59 +0000
831+++ src/server/input/android/android_input_manager.cpp 2013-03-22 17:46:22 +0000
832@@ -18,12 +18,16 @@
833 */
834
835 #include "mir/graphics/viewable_area.h"
836+#include "mir/input/session_target.h"
837+#include "mir/input/surface_target.h"
838
839 #include "android_input_manager.h"
840 #include "android_input_constants.h"
841 #include "android_input_configuration.h"
842 #include "android_input_thread.h"
843 #include "android_input_channel.h"
844+#include "android_input_window_handle.h"
845+#include "android_input_application_handle.h"
846 #include "default_android_input_configuration.h"
847
848 #include <EventHub.h>
849@@ -40,7 +44,8 @@
850 : event_hub(config->the_event_hub()),
851 dispatcher(config->the_dispatcher()),
852 reader_thread(config->the_reader_thread()),
853- dispatcher_thread(config->the_dispatcher_thread())
854+ dispatcher_thread(config->the_dispatcher_thread()),
855+ focused_window_handle(0)
856 {
857 }
858
859@@ -73,6 +78,28 @@
860 return std::make_shared<mia::AndroidInputChannel>();
861 }
862
863+void mia::InputManager::set_input_focus_to(std::shared_ptr<mi::SessionTarget> const& session, std::shared_ptr<mi::SurfaceTarget> const& surface)
864+{
865+ if (focused_window_handle.get())
866+ {
867+ dispatcher->unregisterInputChannel(focused_window_handle->getInfo()->inputChannel);
868+ focused_window_handle.clear();
869+ focused_application_handle.clear();
870+ }
871+
872+ droidinput::Vector<droidinput::sp<droidinput::InputWindowHandle>> windows;
873+ if (surface)
874+ {
875+ focused_application_handle = new mia::InputApplicationHandle(session);
876+ focused_window_handle = new mia::InputWindowHandle(focused_application_handle, surface);
877+ dispatcher->setFocusedApplication(focused_application_handle);
878+
879+ dispatcher->registerInputChannel(focused_window_handle->getInfo()->inputChannel, focused_window_handle, false);
880+ windows.push_back(focused_window_handle);
881+ }
882+ dispatcher->setInputWindows(windows);
883+}
884+
885 std::shared_ptr<mi::InputManager> mi::create_input_manager(
886 const std::initializer_list<std::shared_ptr<mi::EventFilter> const>& event_filters,
887 std::shared_ptr<mg::ViewableArea> const& view_area)
888
889=== modified file 'src/server/input/android/android_input_manager.h'
890--- src/server/input/android/android_input_manager.h 2013-03-21 03:32:59 +0000
891+++ src/server/input/android/android_input_manager.h 2013-03-22 17:46:22 +0000
892@@ -30,6 +30,8 @@
893 {
894 class EventHubInterface;
895 class InputDispatcherInterface;
896+class InputWindowHandle;
897+class InputApplicationHandle;
898 }
899
900 namespace droidinput = android;
901@@ -40,6 +42,7 @@
902 {
903 class ViewableArea;
904 }
905+
906 namespace input
907 {
908 class CursorListener;
909@@ -61,6 +64,7 @@
910
911 std::shared_ptr<InputChannel> make_input_channel();
912
913+ void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& session, std::shared_ptr<input::SurfaceTarget> const& surface);
914
915 protected:
916 InputManager(const InputManager&) = delete;
917@@ -72,6 +76,9 @@
918
919 std::shared_ptr<InputThread> reader_thread;
920 std::shared_ptr<InputThread> dispatcher_thread;
921+
922+ droidinput::sp<droidinput::InputWindowHandle> focused_window_handle;
923+ droidinput::sp<droidinput::InputApplicationHandle> focused_application_handle;
924 };
925
926 }
927
928=== added file 'src/server/input/android/android_input_window_handle.cpp'
929--- src/server/input/android/android_input_window_handle.cpp 1970-01-01 00:00:00 +0000
930+++ src/server/input/android/android_input_window_handle.cpp 2013-03-22 17:46:22 +0000
931@@ -0,0 +1,74 @@
932+/*
933+ * Copyright © 2013 Canonical Ltd.
934+ *
935+ * This program is free software: you can redistribute it and/or modify
936+ * it under the terms of the GNU General Public License version 3 as
937+ * published by the Free Software Foundation.
938+ *
939+ * This program is distributed in the hope that it will be useful,
940+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
941+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
942+ * GNU General Public License for more details.
943+ *
944+ * You should have received a copy of the GNU General Public License
945+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
946+ *
947+ * Authored by: Robert Carr <robert.carr@canonical.com>
948+ */
949+
950+#include "android_input_window_handle.h"
951+#include "android_input_application_handle.h"
952+
953+#include "mir/input/input_channel.h"
954+#include "mir/input/surface_target.h"
955+
956+#include <androidfw/InputTransport.h>
957+
958+#include <limits.h>
959+
960+namespace mi = mir::input;
961+namespace mia = mi::android;
962+
963+mia::InputWindowHandle::InputWindowHandle(droidinput::sp<droidinput::InputApplicationHandle> const& input_app_handle,
964+ std::shared_ptr<mi::SurfaceTarget> const& surface)
965+ : droidinput::InputWindowHandle(input_app_handle),
966+ surface(surface)
967+{
968+ updateInfo();
969+}
970+
971+bool mia::InputWindowHandle::updateInfo()
972+{
973+ if (!mInfo)
974+ {
975+ mInfo = new droidinput::InputWindowInfo();
976+
977+ // TODO: How can we avoid recreating the InputChannel which the InputChannelFactory has already created?
978+ mInfo->inputChannel = new droidinput::InputChannel(droidinput::String8("TODO: Name"),
979+ surface->server_input_fd());
980+ }
981+
982+ mInfo->frameLeft = 0;
983+ mInfo->frameTop = 0;
984+ auto surface_size = surface->size();
985+ mInfo->frameRight = mInfo->frameLeft + surface_size.width.as_uint32_t();
986+ mInfo->frameBottom = mInfo->frameTop + surface_size.height.as_uint32_t();
987+
988+ mInfo->name = droidinput::String8(surface->name().c_str());
989+ mInfo->layoutParamsFlags = droidinput::InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
990+ mInfo->layoutParamsType = droidinput::InputWindowInfo::TYPE_APPLICATION;
991+ mInfo->scaleFactor = 1.f;
992+ mInfo->visible = true;
993+ mInfo->canReceiveKeys = true;
994+ mInfo->hasFocus = true;
995+ mInfo->hasWallpaper = false;
996+ mInfo->paused = false;
997+ mInfo->dispatchingTimeout = INT_MAX;
998+ mInfo->ownerPid = 0;
999+ mInfo->ownerUid = 0;
1000+ mInfo->inputFeatures = 0;
1001+
1002+ // TODO: Set touchableRegion and layer for touch events.
1003+
1004+ return true;
1005+}
1006
1007=== added file 'src/server/input/android/android_input_window_handle.h'
1008--- src/server/input/android/android_input_window_handle.h 1970-01-01 00:00:00 +0000
1009+++ src/server/input/android/android_input_window_handle.h 2013-03-22 17:46:22 +0000
1010@@ -0,0 +1,59 @@
1011+/*
1012+ * Copyright © 2013 Canonical Ltd.
1013+ *
1014+ * This program is free software: you can redistribute it and/or modify
1015+ * it under the terms of the GNU General Public License version 3 as
1016+ * published by the Free Software Foundation.
1017+ *
1018+ * This program is distributed in the hope that it will be useful,
1019+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1020+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1021+ * GNU General Public License for more details.
1022+ *
1023+ * You should have received a copy of the GNU General Public License
1024+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1025+ *
1026+ * Authored by: Robert Carr <robert.carr@canonical.com>
1027+ */
1028+
1029+#ifndef MIR_INPUT_ANDROID_INPUT_WINDOW_HANDLE_H_
1030+#define MIR_INPUT_ANDROID_INPUT_WINDOW_HANDLE_H_
1031+
1032+#include <InputWindow.h>
1033+
1034+#include <memory>
1035+
1036+namespace droidinput = android;
1037+
1038+namespace mir
1039+{
1040+
1041+namespace input
1042+{
1043+class SurfaceTarget;
1044+
1045+namespace android
1046+{
1047+
1048+class InputWindowHandle : public droidinput::InputWindowHandle
1049+{
1050+public:
1051+ InputWindowHandle(droidinput::sp<droidinput::InputApplicationHandle> const& input_app_handle,
1052+ std::shared_ptr<input::SurfaceTarget> const& surface);
1053+ ~InputWindowHandle() {}
1054+
1055+ bool updateInfo();
1056+
1057+protected:
1058+ InputWindowHandle(InputWindowHandle const&) = delete;
1059+ InputWindowHandle& operator=(InputWindowHandle const&) = delete;
1060+
1061+private:
1062+ std::shared_ptr<input::SurfaceTarget> surface;
1063+};
1064+
1065+}
1066+}
1067+} // namespace mir
1068+
1069+#endif // MIR_INPUT_ANDROID_INPUT_WINDOW_HANDLE_H_
1070
1071=== modified file 'src/server/input/android/default_android_input_configuration.cpp'
1072--- src/server/input/android/default_android_input_configuration.cpp 2013-03-06 17:01:51 +0000
1073+++ src/server/input/android/default_android_input_configuration.cpp 2013-03-22 17:46:22 +0000
1074@@ -26,6 +26,8 @@
1075 #include <InputDispatcher.h>
1076 #include <InputReader.h>
1077
1078+#include <string>
1079+
1080 namespace droidinput = android;
1081
1082 namespace mi = mir::input;
1083
1084=== modified file 'src/server/input/android/event_filter_dispatcher_policy.cpp'
1085--- src/server/input/android/event_filter_dispatcher_policy.cpp 2013-03-13 04:54:15 +0000
1086+++ src/server/input/android/event_filter_dispatcher_policy.cpp 2013-03-22 17:46:22 +0000
1087@@ -39,5 +39,5 @@
1088
1089 void mia::EventFilterDispatcherPolicy::interceptKeyBeforeQueueing(const droidinput::KeyEvent* /*key_event*/, uint32_t& policy_flags)
1090 {
1091- policy_flags = droidinput::POLICY_FLAG_FILTERED;
1092+ policy_flags |= droidinput::POLICY_FLAG_PASS_TO_USER;
1093 }
1094
1095=== modified file 'src/server/input/dummy_input_manager.cpp'
1096--- src/server/input/dummy_input_manager.cpp 2013-03-21 03:32:59 +0000
1097+++ src/server/input/dummy_input_manager.cpp 2013-03-22 17:46:22 +0000
1098@@ -28,6 +28,9 @@
1099 void stop() {}
1100 void start() {}
1101 virtual std::shared_ptr<mi::InputChannel> make_input_channel() { return std::shared_ptr<mi::InputChannel>(); }
1102+ void set_input_focus_to(std::shared_ptr<mi::SessionTarget> const& /* session */, std::shared_ptr<mi::SurfaceTarget> const& /* surface */)
1103+ {
1104+ }
1105 };
1106 }
1107
1108
1109=== modified file 'src/server/shell/application_session.cpp'
1110--- src/server/shell/application_session.cpp 2013-03-22 03:33:00 +0000
1111+++ src/server/shell/application_session.cpp 2013-03-22 17:46:22 +0000
1112@@ -82,6 +82,14 @@
1113 return checked_find(id)->second;
1114 }
1115
1116+std::shared_ptr<msh::Surface> msh::ApplicationSession::default_surface() const
1117+{
1118+ if (surfaces.size())
1119+ return surfaces.begin()->second;
1120+ else
1121+ return std::shared_ptr<msh::Surface>();
1122+}
1123+
1124 void msh::ApplicationSession::destroy_surface(mf::SurfaceId id)
1125 {
1126 std::unique_lock<std::mutex> lock(surfaces_mutex);
1127
1128=== modified file 'src/server/shell/registration_order_focus_sequence.cpp'
1129--- src/server/shell/registration_order_focus_sequence.cpp 2013-03-21 03:32:59 +0000
1130+++ src/server/shell/registration_order_focus_sequence.cpp 2013-03-22 17:46:22 +0000
1131@@ -18,7 +18,7 @@
1132
1133 #include "mir/shell/registration_order_focus_sequence.h"
1134 #include "mir/frontend/session.h"
1135-#include "mir/frontend/session_container.h"
1136+#include "mir/shell/session_container.h"
1137
1138 #include <boost/throw_exception.hpp>
1139
1140
1141=== modified file 'src/server/shell/session_container.cpp'
1142--- src/server/shell/session_container.cpp 2013-03-21 03:32:59 +0000
1143+++ src/server/shell/session_container.cpp 2013-03-22 17:46:22 +0000
1144@@ -16,7 +16,7 @@
1145 * Authored By: Robert Carr <robert.carr@canonical.com>
1146 */
1147
1148-#include "mir/frontend/session_container.h"
1149+#include "mir/shell/session_container.h"
1150 #include "mir/frontend/session.h"
1151
1152 #include <boost/throw_exception.hpp>
1153@@ -42,7 +42,6 @@
1154 void msh::SessionContainer::insert_session(std::shared_ptr<mf::Session> const& session)
1155 {
1156 std::unique_lock<std::mutex> lk(guard);
1157- auto name = session->name();
1158
1159 apps.push_back(session);
1160 }
1161
1162=== modified file 'src/server/shell/session_manager.cpp'
1163--- src/server/shell/session_manager.cpp 2013-03-21 03:32:59 +0000
1164+++ src/server/shell/session_manager.cpp 2013-03-22 17:46:22 +0000
1165@@ -18,10 +18,11 @@
1166
1167 #include "mir/shell/session_manager.h"
1168 #include "mir/shell/application_session.h"
1169-#include "mir/frontend/session_container.h"
1170+#include "mir/shell/session_container.h"
1171 #include "mir/shell/surface_factory.h"
1172 #include "mir/shell/focus_sequence.h"
1173 #include "mir/shell/focus_setter.h"
1174+#include "mir/shell/session.h"
1175
1176 #include <memory>
1177 #include <cassert>
1178@@ -67,8 +68,9 @@
1179
1180 inline void msh::SessionManager::set_focus_to(std::shared_ptr<mf::Session> const& next_focus)
1181 {
1182- focus_application = next_focus;
1183- focus_setter->set_focus_to(next_focus);
1184+ auto shell_session = std::dynamic_pointer_cast<msh::Session>(next_focus);
1185+ focus_application = shell_session;
1186+ focus_setter->set_focus_to(shell_session);
1187 }
1188
1189 void msh::SessionManager::close_session(std::shared_ptr<mf::Session> const& session)
1190
1191=== modified file 'src/server/shell/single_visibility_focus_mechanism.cpp'
1192--- src/server/shell/single_visibility_focus_mechanism.cpp 2013-03-21 03:32:59 +0000
1193+++ src/server/shell/single_visibility_focus_mechanism.cpp 2013-03-22 17:46:22 +0000
1194@@ -16,25 +16,33 @@
1195 * Authored By: Robert Carr <robert.carr@canonical.com>
1196 */
1197
1198-#include "mir/frontend/session_container.h"
1199+#include "mir/shell/session_container.h"
1200 #include "mir/frontend/session.h"
1201 #include "mir/shell/single_visibility_focus_mechanism.h"
1202+#include "mir/shell/input_focus_selector.h"
1203+
1204+#include "mir/shell/session.h"
1205+#include "surface.h" // TODO: Cleanup headers ~racarr
1206
1207 namespace mf = mir::frontend;
1208 namespace msh = mir::shell;
1209
1210-msh::SingleVisibilityFocusMechanism::SingleVisibilityFocusMechanism(std::shared_ptr<msh::SessionContainer> const& app_container) :
1211- app_container(app_container)
1212+msh::SingleVisibilityFocusMechanism::SingleVisibilityFocusMechanism(std::shared_ptr<msh::SessionContainer> const& app_container,
1213+ std::shared_ptr<msh::InputFocusSelector> const& input_selector)
1214+ : app_container(app_container),
1215+ input_selector(input_selector)
1216 {
1217 }
1218
1219-void msh::SingleVisibilityFocusMechanism::set_focus_to(std::shared_ptr<mf::Session> const& focus_session)
1220+void msh::SingleVisibilityFocusMechanism::set_focus_to(std::shared_ptr<msh::Session> const& focus_session)
1221 {
1222 app_container->for_each(
1223 [&](std::shared_ptr<mf::Session> const& session) {
1224 if (session == focus_session)
1225 {
1226 session->show();
1227+
1228+ input_selector->set_input_focus_to(focus_session, focus_session->default_surface());
1229 }
1230 else
1231 {
1232
1233=== modified file 'src/server/shell/surface.cpp'
1234--- src/server/shell/surface.cpp 2013-03-21 04:03:36 +0000
1235+++ src/server/shell/surface.cpp 2013-03-22 17:46:22 +0000
1236@@ -89,6 +89,18 @@
1237 }
1238 }
1239
1240+std::string msh::Surface::name() const
1241+{
1242+ if (auto const& s = surface.lock())
1243+ {
1244+ return s->name();
1245+ }
1246+ else
1247+ {
1248+ BOOST_THROW_EXCEPTION(std::runtime_error("Invalid surface"));
1249+ }
1250+}
1251+
1252 mir::geometry::PixelFormat msh::Surface::pixel_format() const
1253 {
1254 if (auto const& s = surface.lock())
1255@@ -135,6 +147,13 @@
1256 return input_channel->client_fd();
1257 }
1258
1259+int msh::Surface::server_input_fd() const
1260+{
1261+ if (!supports_input())
1262+ BOOST_THROW_EXCEPTION(std::logic_error("Surface does not support input"));
1263+ return input_channel->server_fd();
1264+}
1265+
1266 int msh::Surface::configure(MirSurfaceAttrib attrib, int value)
1267 {
1268 int result = 0;
1269
1270=== modified file 'src/server/shell/surface.h'
1271--- src/server/shell/surface.h 2013-03-21 04:03:36 +0000
1272+++ src/server/shell/surface.h 2013-03-22 17:46:22 +0000
1273@@ -22,8 +22,12 @@
1274
1275 #include "mir/frontend/surface.h"
1276 #include "mir/surfaces/surface.h"
1277+#include "mir/input/surface_target.h"
1278+
1279 #include "mir_toolkit/common.h"
1280
1281+#include <string>
1282+
1283 namespace mir
1284 {
1285 namespace frontend
1286@@ -39,7 +43,7 @@
1287 {
1288 class SurfaceBuilder;
1289
1290-class Surface : public frontend::Surface
1291+class Surface : public frontend::Surface, public input::SurfaceTarget
1292 {
1293 public:
1294 Surface(
1295@@ -56,6 +60,8 @@
1296
1297 virtual void shutdown();
1298
1299+ virtual std::string name() const;
1300+
1301 virtual geometry::Size size() const;
1302
1303 virtual geometry::PixelFormat pixel_format() const;
1304@@ -66,6 +72,7 @@
1305
1306 virtual bool supports_input() const;
1307 virtual int client_input_fd() const;
1308+ virtual int server_input_fd() const;
1309
1310 virtual int configure(MirSurfaceAttrib attrib, int value);
1311 virtual MirSurfaceType type() const;
1312
1313=== modified file 'tests/acceptance-tests/CMakeLists.txt'
1314--- tests/acceptance-tests/CMakeLists.txt 2013-03-21 03:32:59 +0000
1315+++ tests/acceptance-tests/CMakeLists.txt 2013-03-22 17:46:22 +0000
1316@@ -9,7 +9,7 @@
1317 test_surfaceloop.cpp
1318 test_test_framework.cpp
1319 test_focus_management_api.cpp
1320- test_surface_focus.cpp
1321+ test_focus_selection.cpp
1322 )
1323
1324 # TODO Disabled in binder version as this test uses detect_server() and that
1325
1326=== renamed file 'tests/acceptance-tests/test_surface_focus.cpp' => 'tests/acceptance-tests/test_focus_selection.cpp'
1327--- tests/acceptance-tests/test_surface_focus.cpp 2013-03-15 23:15:45 +0000
1328+++ tests/acceptance-tests/test_focus_selection.cpp 2013-03-22 17:46:22 +0000
1329@@ -18,21 +18,24 @@
1330
1331 #include "mir_toolkit/mir_client_library.h"
1332
1333-#include "mir/frontend/session_container.h"
1334+#include "mir/shell/session_container.h"
1335 #include "mir/shell/registration_order_focus_sequence.h"
1336 #include "mir/shell/consuming_placement_strategy.h"
1337 #include "mir/shell/organising_surface_factory.h"
1338 #include "mir/shell/session_manager.h"
1339 #include "mir/graphics/display.h"
1340+#include "mir/shell/input_focus_selector.h"
1341
1342 #include "mir_test_framework/display_server_test_fixture.h"
1343 #include "mir_test_doubles/mock_focus_setter.h"
1344+#include "mir_test_doubles/mock_input_focus_selector.h"
1345
1346 #include <gtest/gtest.h>
1347 #include <gmock/gmock.h>
1348
1349 namespace mf = mir::frontend;
1350 namespace msh = mir::shell;
1351+namespace mi = mir::input;
1352 namespace mtd = mir::test::doubles;
1353 namespace mtf = mir_test_framework;
1354
1355@@ -87,13 +90,48 @@
1356 MirConnection* connection;
1357 MirSurface* surface;
1358 };
1359+
1360+struct SurfaceCreatingClient : ClientConfigCommon
1361+{
1362+ void exec()
1363+ {
1364+ mir_wait_for(mir_connect(
1365+ mir_test_socket,
1366+ __PRETTY_FUNCTION__,
1367+ connection_callback,
1368+ this));
1369+ ASSERT_TRUE(connection != NULL);
1370+ MirSurfaceParameters const request_params =
1371+ {
1372+ __PRETTY_FUNCTION__,
1373+ 640, 480,
1374+ mir_pixel_format_abgr_8888,
1375+ mir_buffer_usage_hardware
1376+ };
1377+ mir_wait_for(mir_surface_create(connection, &request_params, create_surface_callback, this));
1378+ mir_connection_release(connection);
1379+ }
1380+};
1381+
1382 }
1383
1384 namespace
1385 {
1386 MATCHER(NonNullSession, "")
1387 {
1388- return arg != std::shared_ptr<mf::Session>();
1389+ return arg != std::shared_ptr<msh::Session>();
1390+}
1391+MATCHER(NonNullSessionTarget, "")
1392+{
1393+ return arg != std::shared_ptr<mi::SessionTarget>();
1394+}
1395+MATCHER(NonNullSurfaceTarget, "")
1396+{
1397+ return arg != std::shared_ptr<mi::SurfaceTarget>();
1398+}
1399+MATCHER(NullSurfaceTarget, "")
1400+{
1401+ return arg == std::shared_ptr<mi::SurfaceTarget>();
1402 }
1403 }
1404
1405@@ -132,31 +170,46 @@
1406
1407 launch_server_process(server_config);
1408
1409- struct ClientConfig : ClientConfigCommon
1410+ SurfaceCreatingClient client;
1411+
1412+ launch_client_process(client);
1413+}
1414+
1415+TEST_F(BespokeDisplayServerTestFixture, surfaces_receive_input_focus_when_created)
1416+{
1417+ struct ServerConfig : TestingServerConfiguration
1418 {
1419- void exec()
1420- {
1421- mir_wait_for(mir_connect(
1422- mir_test_socket,
1423- __PRETTY_FUNCTION__,
1424- connection_callback,
1425- this));
1426-
1427- ASSERT_TRUE(connection != NULL);
1428-
1429- MirSurfaceParameters const request_params =
1430+ std::shared_ptr<mtd::MockInputFocusSelector> focus_selector;
1431+ bool expected;
1432+
1433+ ServerConfig()
1434+ : focus_selector(std::make_shared<mtd::MockInputFocusSelector>()),
1435+ expected(false)
1436+ {
1437+ }
1438+
1439+ std::shared_ptr<msh::InputFocusSelector>
1440+ the_input_focus_selector() override
1441+ {
1442+ using namespace ::testing;
1443+
1444+ if (!expected)
1445 {
1446- __PRETTY_FUNCTION__,
1447- 640, 480,
1448- mir_pixel_format_abgr_8888,
1449- mir_buffer_usage_hardware
1450- };
1451-
1452- mir_wait_for(mir_surface_create(connection, &request_params, create_surface_callback, this));
1453-
1454- mir_connection_release(connection);
1455+ InSequence seq;
1456+
1457+ EXPECT_CALL(*focus_selector, set_input_focus_to(NonNullSessionTarget(), NullSurfaceTarget())).Times(1);
1458+ EXPECT_CALL(*focus_selector, set_input_focus_to(NonNullSessionTarget(), NonNullSurfaceTarget())).Times(1);
1459+ expected = true;
1460+ }
1461+
1462+ return focus_selector;
1463 }
1464- } focus_config;
1465+ } server_config;
1466+
1467+
1468+ launch_server_process(server_config);
1469+
1470+ SurfaceCreatingClient client;
1471
1472- launch_client_process(focus_config);
1473+ launch_client_process(client);
1474 }
1475
1476=== modified file 'tests/behavior-tests/session_management_context.cpp'
1477--- tests/behavior-tests/session_management_context.cpp 2013-03-21 03:32:59 +0000
1478+++ tests/behavior-tests/session_management_context.cpp 2013-03-22 17:46:22 +0000
1479@@ -23,7 +23,7 @@
1480 #include "mir/frontend/session.h"
1481 #include "mir/shell/registration_order_focus_sequence.h"
1482 #include "mir/shell/single_visibility_focus_mechanism.h"
1483-#include "mir/frontend/session_container.h"
1484+#include "mir/shell/session_container.h"
1485 #include "mir/frontend/shell.h"
1486 #include "mir/input/input_channel.h"
1487 #include "mir/shell/surface_factory.h"
1488
1489=== modified file 'tests/integration-tests/CMakeLists.txt'
1490--- tests/integration-tests/CMakeLists.txt 2013-03-19 09:51:24 +0000
1491+++ tests/integration-tests/CMakeLists.txt 2013-03-22 17:46:22 +0000
1492@@ -10,6 +10,7 @@
1493 add_subdirectory(client/)
1494 add_subdirectory(compositor/)
1495 add_subdirectory(frontend/)
1496+add_subdirectory(shell/)
1497 add_subdirectory(process/)
1498 if (NOT MIR_DISABLE_INPUT)
1499 add_subdirectory(input/)
1500
1501=== modified file 'tests/integration-tests/cucumber/test_session_management_context.cpp'
1502--- tests/integration-tests/cucumber/test_session_management_context.cpp 2013-03-21 03:32:59 +0000
1503+++ tests/integration-tests/cucumber/test_session_management_context.cpp 2013-03-22 17:46:22 +0000
1504@@ -25,6 +25,8 @@
1505 #include "mir/graphics/viewable_area.h"
1506
1507 #include "mir_test_doubles/mock_session.h"
1508+#include "mir_test_doubles/stub_surface_builder.h"
1509+#include "mir_test_doubles/mock_surface.h"
1510 #include "mir_test_doubles/mock_shell.h"
1511 #include "mir_test/fake_shared.h"
1512
1513@@ -52,24 +54,6 @@
1514 MOCK_METHOD0(the_compositor, std::shared_ptr<mc::Compositor>());
1515 };
1516
1517-struct MockSurface : public mf::Surface
1518-{
1519- MOCK_METHOD0(hide, void());
1520- MOCK_METHOD0(show, void());
1521- MOCK_METHOD0(destroy, void());
1522- MOCK_METHOD0(shutdown, void());
1523- MOCK_METHOD0(advance_client_buffer, void());
1524-
1525- MOCK_CONST_METHOD0(size, mir::geometry::Size ());
1526- MOCK_CONST_METHOD0(pixel_format, mir::geometry::PixelFormat ());
1527- MOCK_CONST_METHOD0(client_buffer, std::shared_ptr<mc::Buffer> ());
1528-
1529- MOCK_METHOD2(configure, int(MirSurfaceAttrib, int));
1530-
1531- MOCK_CONST_METHOD0(supports_input, bool());
1532- MOCK_CONST_METHOD0(client_input_fd, int());
1533-};
1534-
1535 MATCHER_P(NamedWindowWithNoGeometry, name, "")
1536 {
1537 if (arg.name != name)
1538@@ -181,7 +165,7 @@
1539 using namespace ::testing;
1540
1541 mtd::MockSession session;
1542- MockSurface surface;
1543+ mtd::MockSurface surface(std::make_shared<mtd::StubSurfaceBuilder>());
1544
1545 EXPECT_CALL(shell, open_session(test_window_name)).Times(1)
1546 .WillOnce(Return(mt::fake_shared<mf::Session>(session)));
1547
1548=== modified file 'tests/integration-tests/frontend/CMakeLists.txt'
1549--- tests/integration-tests/frontend/CMakeLists.txt 2013-03-13 04:54:15 +0000
1550+++ tests/integration-tests/frontend/CMakeLists.txt 2013-03-22 17:46:22 +0000
1551@@ -1,7 +1,6 @@
1552 list(
1553 APPEND INTEGRATION_TESTS_SRCS
1554 ${CMAKE_CURRENT_SOURCE_DIR}/test_application_mediator_report.cpp
1555- ${CMAKE_CURRENT_SOURCE_DIR}/test_session_manager.cpp
1556 )
1557
1558 set(
1559
1560=== modified file 'tests/integration-tests/input/android/test_android_input_manager.cpp'
1561--- tests/integration-tests/input/android/test_android_input_manager.cpp 2013-03-21 03:32:59 +0000
1562+++ tests/integration-tests/input/android/test_android_input_manager.cpp 2013-03-22 17:46:22 +0000
1563@@ -18,22 +18,32 @@
1564 */
1565
1566 #include "mir/input/event_filter.h"
1567+#include "mir/frontend/surface_creation_parameters.h"
1568+
1569 #include "src/server/input/android/default_android_input_configuration.h"
1570 #include "src/server/input/android/android_input_manager.h"
1571+#include "src/server/input/android/dummy_input_dispatcher_policy.h"
1572+#include "src/server/input/android/event_filter_dispatcher_policy.h"
1573
1574 #include "mir_test/fake_shared.h"
1575 #include "mir_test/fake_event_hub.h"
1576 #include "mir_test/fake_event_hub_input_configuration.h"
1577 #include "mir_test_doubles/mock_event_filter.h"
1578 #include "mir_test_doubles/mock_viewable_area.h"
1579+#include "mir_test_doubles/stub_session_target.h"
1580+#include "mir_test_doubles/stub_surface_target.h"
1581 #include "mir_test/wait_condition.h"
1582 #include "mir_test/event_factory.h"
1583
1584 #include <EventHub.h>
1585+#include <InputDispatcher.h>
1586
1587 #include <gmock/gmock.h>
1588 #include <gtest/gtest.h>
1589
1590+#include <sys/types.h>
1591+#include <sys/socket.h>
1592+
1593 namespace mi = mir::input;
1594 namespace mia = mir::input::android;
1595 namespace mis = mir::input::synthesis;
1596@@ -154,3 +164,111 @@
1597 wait_condition.wait_for_at_most_seconds(1);
1598 }
1599
1600+namespace
1601+{
1602+
1603+struct MockDispatcherPolicy : public mia::EventFilterDispatcherPolicy
1604+{
1605+ MockDispatcherPolicy(std::shared_ptr<mi::EventFilter> const& filter)
1606+ : EventFilterDispatcherPolicy(filter)
1607+ {
1608+ }
1609+ MOCK_METHOD3(interceptKeyBeforeDispatching, nsecs_t(droidinput::sp<droidinput::InputWindowHandle> const&,
1610+ droidinput::KeyEvent const*, uint32_t));
1611+};
1612+
1613+struct TestingInputConfiguration : public mtd::FakeEventHubInputConfiguration
1614+{
1615+ TestingInputConfiguration(std::shared_ptr<mi::EventFilter> const& filter,
1616+ std::shared_ptr<mg::ViewableArea> const& view_area,
1617+ std::shared_ptr<mi::CursorListener> const& cursor_listener)
1618+ : FakeEventHubInputConfiguration({}, view_area, cursor_listener),
1619+ dispatcher_policy(new MockDispatcherPolicy(filter))
1620+ {
1621+ }
1622+ droidinput::sp<droidinput::InputDispatcherPolicyInterface> the_dispatcher_policy()
1623+ {
1624+ return dispatcher_policy;
1625+ }
1626+ droidinput::sp<MockDispatcherPolicy> the_mock_dispatcher_policy()
1627+ {
1628+ return dispatcher_policy;
1629+ }
1630+
1631+ droidinput::sp<MockDispatcherPolicy> dispatcher_policy;
1632+};
1633+
1634+struct AndroidInputManagerDispatcherInterceptSetup : public testing::Test
1635+{
1636+ AndroidInputManagerDispatcherInterceptSetup()
1637+ {
1638+ configuration = std::make_shared<TestingInputConfiguration>(
1639+ mt::fake_shared(event_filter),
1640+ mt::fake_shared(viewable_area), null_cursor_listener);
1641+ fake_event_hub = configuration->the_fake_event_hub();
1642+
1643+ ON_CALL(viewable_area, view_area())
1644+ .WillByDefault(Return(default_view_area));
1645+ input_manager = std::make_shared<mia::InputManager>(configuration);
1646+
1647+ dispatcher_policy = configuration->the_mock_dispatcher_policy();
1648+
1649+ }
1650+
1651+ // TODO: It would be nice if it were possible to mock the interface between
1652+ // droidinput::InputChannel and droidinput::InputDispatcher rather than use
1653+ // valid fds to allow non-throwing construction of a real input channel.
1654+ void SetUp()
1655+ {
1656+ test_input_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
1657+ input_manager->start();
1658+ }
1659+ void TearDown()
1660+ {
1661+ input_manager->stop();
1662+ close(test_input_fd);
1663+ }
1664+
1665+ MockEventFilter event_filter;
1666+ NiceMock<mtd::MockViewableArea> viewable_area;
1667+ std::shared_ptr<TestingInputConfiguration> configuration;
1668+ mia::FakeEventHub* fake_event_hub;
1669+ droidinput::sp<MockDispatcherPolicy> dispatcher_policy;
1670+
1671+ std::shared_ptr<mia::InputManager> input_manager;
1672+
1673+ int test_input_fd;
1674+};
1675+
1676+MATCHER_P(WindowHandleWithInputFd, input_fd, "")
1677+{
1678+ if (arg->getInputChannel()->getFd() == input_fd)
1679+ return true;
1680+ return false;
1681+}
1682+
1683+}
1684+
1685+TEST_F(AndroidInputManagerDispatcherInterceptSetup, server_input_fd_of_focused_surface_is_sent_unfiltered_key_events)
1686+{
1687+ using namespace ::testing;
1688+
1689+ WaitCondition wait_condition;
1690+
1691+ mtd::StubSessionTarget session;
1692+ mtd::StubSurfaceTarget surface(test_input_fd);
1693+
1694+ EXPECT_CALL(event_filter, handles(_)).Times(1).WillOnce(Return(false));
1695+ // We return -1 here to skip publishing of the event (to an unconnected test socket!).
1696+ EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(test_input_fd), _, _))
1697+ .Times(1).WillOnce(DoAll(WakeUp(&wait_condition), Return(-1)));
1698+
1699+ input_manager->set_input_focus_to(mt::fake_shared(session), mt::fake_shared(surface));
1700+
1701+ fake_event_hub->synthesize_builtin_keyboard_added();
1702+ fake_event_hub->synthesize_device_scan_complete();
1703+ fake_event_hub->synthesize_event(mis::a_key_down_event()
1704+ .of_scancode(KEY_ENTER));
1705+
1706+ wait_condition.wait_for_at_most_seconds(1);
1707+}
1708
1709=== added directory 'tests/integration-tests/shell'
1710=== added file 'tests/integration-tests/shell/CMakeLists.txt'
1711--- tests/integration-tests/shell/CMakeLists.txt 1970-01-01 00:00:00 +0000
1712+++ tests/integration-tests/shell/CMakeLists.txt 2013-03-22 17:46:22 +0000
1713@@ -0,0 +1,9 @@
1714+list(
1715+ APPEND INTEGRATION_TESTS_SRCS
1716+ ${CMAKE_CURRENT_SOURCE_DIR}/test_session_manager.cpp
1717+)
1718+
1719+set(
1720+ INTEGRATION_TESTS_SRCS
1721+ ${INTEGRATION_TESTS_SRCS}
1722+ PARENT_SCOPE)
1723
1724=== renamed file 'tests/integration-tests/frontend/test_session_manager.cpp' => 'tests/integration-tests/shell/test_session_manager.cpp'
1725--- tests/integration-tests/frontend/test_session_manager.cpp 2013-03-21 03:32:59 +0000
1726+++ tests/integration-tests/shell/test_session_manager.cpp 2013-03-22 17:46:22 +0000
1727@@ -17,13 +17,14 @@
1728 */
1729
1730 #include "mir/shell/session_manager.h"
1731+#include "mir/shell/session.h"
1732+#include "mir/shell/focus_sequence.h"
1733+#include "mir/shell/focus_setter.h"
1734+#include "mir/shell/registration_order_focus_sequence.h"
1735+#include "mir/shell/session_container.h"
1736 #include "mir/surfaces/buffer_bundle.h"
1737 #include "mir/surfaces/surface.h"
1738 #include "mir/compositor/buffer_swapper.h"
1739-#include "mir/shell/focus_sequence.h"
1740-#include "mir/shell/focus_setter.h"
1741-#include "mir/shell/registration_order_focus_sequence.h"
1742-#include "mir/frontend/session_container.h"
1743 #include "mir/frontend/surface_creation_parameters.h"
1744
1745 #include <gmock/gmock.h>
1746@@ -31,6 +32,7 @@
1747 #include "mir_test/gmock_fixes.h"
1748 #include "mir_test/fake_shared.h"
1749 #include "mir_test_doubles/mock_surface_factory.h"
1750+#include "mir_test_doubles/mock_focus_setter.h"
1751
1752 namespace mc = mir::compositor;
1753 namespace mf = mir::frontend;
1754@@ -39,23 +41,13 @@
1755 namespace mt = mir::test;
1756 namespace mtd = mir::test::doubles;
1757
1758-namespace
1759-{
1760-
1761-struct MockFocusSetter: public msh::FocusSetter
1762-{
1763- MOCK_METHOD1(set_focus_to, void(std::shared_ptr<mf::Session> const&));
1764-};
1765-
1766-}
1767-
1768 TEST(TestSessionManagerAndFocusSelectionStrategy, cycle_focus)
1769 {
1770 using namespace ::testing;
1771 mtd::MockSurfaceFactory surface_factory;
1772 std::shared_ptr<msh::SessionContainer> container(new msh::SessionContainer());
1773 msh::RegistrationOrderFocusSequence sequence(container);
1774- MockFocusSetter focus_changer;
1775+ mtd::MockFocusSetter focus_changer;
1776 std::shared_ptr<mf::Session> new_session;
1777
1778 msh::SessionManager session_manager(
1779@@ -72,9 +64,9 @@
1780
1781 {
1782 InSequence seq;
1783- EXPECT_CALL(focus_changer, set_focus_to(session1)).Times(1);
1784- EXPECT_CALL(focus_changer, set_focus_to(session2)).Times(1);
1785- EXPECT_CALL(focus_changer, set_focus_to(session3)).Times(1);
1786+ EXPECT_CALL(focus_changer, set_focus_to(Eq(session1))).Times(1);
1787+ EXPECT_CALL(focus_changer, set_focus_to(Eq(session2))).Times(1);
1788+ EXPECT_CALL(focus_changer, set_focus_to(Eq(session3))).Times(1);
1789 }
1790
1791 session_manager.focus_next();
1792@@ -88,7 +80,7 @@
1793 mtd::MockSurfaceFactory surface_factory;
1794 std::shared_ptr<msh::SessionContainer> model(new msh::SessionContainer());
1795 msh::RegistrationOrderFocusSequence sequence(model);
1796- MockFocusSetter focus_changer;
1797+ mtd::MockFocusSetter focus_changer;
1798 std::shared_ptr<mf::Session> new_session;
1799
1800 msh::SessionManager session_manager(
1801@@ -105,8 +97,8 @@
1802
1803 {
1804 InSequence seq;
1805- EXPECT_CALL(focus_changer, set_focus_to(session2)).Times(1);
1806- EXPECT_CALL(focus_changer, set_focus_to(session1)).Times(1);
1807+ EXPECT_CALL(focus_changer, set_focus_to(Eq(session2))).Times(1);
1808+ EXPECT_CALL(focus_changer, set_focus_to(Eq(session1))).Times(1);
1809 }
1810
1811 session_manager.close_session(session3);
1812
1813=== modified file 'tests/mir_test_doubles/fake_event_hub.cpp'
1814--- tests/mir_test_doubles/fake_event_hub.cpp 2013-01-11 23:47:40 +0000
1815+++ tests/mir_test_doubles/fake_event_hub.cpp 2013-03-22 17:46:22 +0000
1816@@ -2,6 +2,7 @@
1817
1818 #include <androidfw/Keyboard.h>
1819 #include <thread>
1820+#include <chrono>
1821
1822 using droidinput::AxisInfo;
1823 using droidinput::InputDeviceIdentifier;
1824@@ -300,7 +301,7 @@
1825 void mia::FakeEventHub::synthesize_event(const mis::KeyParameters &parameters)
1826 {
1827 RawEvent event;
1828- event.when = 0;
1829+ event.when = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
1830 event.type = EV_KEY;
1831 event.code = parameters.scancode;
1832
1833@@ -321,7 +322,7 @@
1834 void mia::FakeEventHub::synthesize_event(const mis::ButtonParameters &parameters)
1835 {
1836 RawEvent event;
1837- event.when = 0;
1838+ event.when = 0; // TODO: This may need a timestamp to go over the wire ~racarr
1839 event.type = EV_KEY;
1840 event.code = parameters.button;
1841
1842
1843=== modified file 'tests/mir_test_framework/testing_server_options.cpp'
1844--- tests/mir_test_framework/testing_server_options.cpp 2013-03-21 03:32:59 +0000
1845+++ tests/mir_test_framework/testing_server_options.cpp 2013-03-22 17:46:22 +0000
1846@@ -41,6 +41,7 @@
1847 namespace mc = mir::compositor;
1848 namespace mg = mir::graphics;
1849 namespace mi = mir::input;
1850+namespace mf = mir::frontend;
1851 namespace mtf = mir_test_framework;
1852 namespace mtd = mir::test::doubles;
1853
1854@@ -139,6 +140,10 @@
1855 {
1856 return std::make_shared<StubInputChannel>();
1857 }
1858+
1859+ void set_input_focus_to(std::shared_ptr<mi::SessionTarget> const& /* session */, std::shared_ptr<mi::SurfaceTarget> const& /* surface */)
1860+ {
1861+ }
1862 };
1863 }
1864
1865
1866=== modified file 'tests/unit-tests/input/android/CMakeLists.txt'
1867--- tests/unit-tests/input/android/CMakeLists.txt 2013-03-21 03:32:59 +0000
1868+++ tests/unit-tests/input/android/CMakeLists.txt 2013-03-22 17:46:22 +0000
1869@@ -6,6 +6,8 @@
1870 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_reader_policy.cpp
1871 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_manager.cpp
1872 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_communication_package.cpp
1873+ ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_application_handle.cpp
1874+ ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_window_handle.cpp
1875 )
1876
1877 set(
1878
1879=== added file 'tests/unit-tests/input/android/test_android_input_application_handle.cpp'
1880--- tests/unit-tests/input/android/test_android_input_application_handle.cpp 1970-01-01 00:00:00 +0000
1881+++ tests/unit-tests/input/android/test_android_input_application_handle.cpp 2013-03-22 17:46:22 +0000
1882@@ -0,0 +1,58 @@
1883+/*
1884+ * Copyright © 2013 Canonical Ltd.
1885+ *
1886+ * This program is free software: you can redistribute it and/or modify
1887+ * it under the terms of the GNU General Public License version 3 as
1888+ * published by the Free Software Foundation.
1889+ *
1890+ * This program is distributed in the hope that it will be useful,
1891+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1892+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1893+ * GNU General Public License for more details.
1894+ *
1895+ * You should have received a copy of the GNU General Public License
1896+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1897+ *
1898+ * Authored by: Robert Carr <robert.carr@canonical.com>
1899+ */
1900+
1901+#include "src/server/input/android/android_input_application_handle.h"
1902+
1903+#include "mir/input/session_target.h"
1904+
1905+#include "mir_test/fake_shared.h"
1906+
1907+#include <gtest/gtest.h>
1908+#include <gmock/gmock.h>
1909+
1910+#include <limits.h>
1911+
1912+namespace mi = mir::input;
1913+namespace mia = mi::android;
1914+namespace mt = mir::test;
1915+
1916+namespace
1917+{
1918+struct MockSessionHandle : public mi::SessionTarget
1919+{
1920+ MOCK_CONST_METHOD0(name, std::string());
1921+};
1922+}
1923+
1924+
1925+TEST(AndroidInputApplicationHandle, takes_name_from_session_and_specifies_max_timeout)
1926+{
1927+ using namespace ::testing;
1928+ std::string const testing_session_name = "Cats";
1929+ MockSessionHandle session;
1930+
1931+ EXPECT_CALL(session, name()).Times(AtLeast(1))
1932+ .WillRepeatedly(Return(testing_session_name));
1933+ mia::InputApplicationHandle application_handle(mt::fake_shared(session));
1934+ EXPECT_TRUE(application_handle.updateInfo());
1935+ auto info = application_handle.getInfo();
1936+ EXPECT_EQ(INT_MAX, info->dispatchingTimeout);
1937+ EXPECT_EQ(droidinput::String8(testing_session_name.c_str()), info->name);
1938+}
1939+
1940+
1941
1942=== modified file 'tests/unit-tests/input/android/test_android_input_manager.cpp'
1943--- tests/unit-tests/input/android/test_android_input_manager.cpp 2013-03-21 03:32:59 +0000
1944+++ tests/unit-tests/input/android/test_android_input_manager.cpp 2013-03-22 17:46:22 +0000
1945@@ -22,9 +22,13 @@
1946 #include "src/server/input/android/android_input_constants.h"
1947
1948 #include "mir/input/input_channel.h"
1949+#include "mir/input/session_target.h"
1950+#include "mir/input/surface_target.h"
1951
1952+#include "mir_test/fake_shared.h"
1953 #include "mir_test_doubles/mock_viewable_area.h"
1954-#include "mir_test/fake_shared.h"
1955+#include "mir_test_doubles/stub_session_target.h"
1956+#include "mir_test_doubles/stub_surface_target.h"
1957
1958 #include <InputDispatcher.h>
1959 #include <InputListener.h>
1960@@ -126,7 +130,7 @@
1961
1962 struct AndroidInputManagerSetup : public testing::Test
1963 {
1964- void SetUp()
1965+ AndroidInputManagerSetup()
1966 {
1967 using namespace ::testing;
1968
1969@@ -207,3 +211,91 @@
1970 EXPECT_GT(package->client_fd(), 0);
1971 EXPECT_GT(package->server_fd(), 0);
1972 }
1973+
1974+namespace
1975+{
1976+
1977+static bool
1978+application_handle_matches_session(droidinput::sp<droidinput::InputApplicationHandle> const& handle,
1979+ std::shared_ptr<mi::SessionTarget> const& session)
1980+{
1981+ if (handle->getName() != droidinput::String8(session->name().c_str()))
1982+ return false;
1983+ return true;
1984+}
1985+
1986+static bool
1987+window_handle_matches_session_and_surface(droidinput::sp<droidinput::InputWindowHandle> const& handle,
1988+ std::shared_ptr<mi::SessionTarget> const& session,
1989+ std::shared_ptr<mi::SurfaceTarget> const& surface)
1990+{
1991+ if (!application_handle_matches_session(handle->inputApplicationHandle, session))
1992+ return false;
1993+ if (handle->getInputChannel()->getFd() != surface->server_input_fd())
1994+ return false;
1995+ return true;
1996+}
1997+
1998+MATCHER_P2(WindowHandleFor, session, surface, "")
1999+{
2000+ return window_handle_matches_session_and_surface(arg, session, surface);
2001+}
2002+
2003+MATCHER_P(ApplicationHandleFor, session, "")
2004+{
2005+ return application_handle_matches_session(arg, session);
2006+}
2007+
2008+MATCHER_P2(VectorContainingWindowHandleFor, session, surface, "")
2009+{
2010+ auto i = arg.size();
2011+ for (i = 0; i < arg.size(); i++)
2012+ {
2013+ if (window_handle_matches_session_and_surface(arg[i], session, surface))
2014+ return true;
2015+ }
2016+ return false;
2017+}
2018+
2019+MATCHER(EmptyVector, "")
2020+{
2021+ return arg.size() == 0;
2022+}
2023+
2024+// TODO: It would be nice if it were possible to mock the interface between
2025+// droidinput::InputChannel and droidinput::InputDispatcher rather than use
2026+// valid fds to allow non-throwing construction of a real input channel.
2027+struct AndroidInputManagerFdSetup : public AndroidInputManagerSetup
2028+{
2029+ void SetUp() override
2030+ {
2031+ test_input_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
2032+ }
2033+ void TearDown() override
2034+ {
2035+ close(test_input_fd);
2036+ }
2037+ int test_input_fd;
2038+};
2039+
2040+}
2041+
2042+TEST_F(AndroidInputManagerFdSetup, set_input_focus)
2043+{
2044+ using namespace ::testing;
2045+
2046+ auto session = std::make_shared<mtd::StubSessionTarget>();
2047+ auto surface = std::make_shared<mtd::StubSurfaceTarget>(test_input_fd);
2048+
2049+ EXPECT_CALL(*dispatcher, registerInputChannel(_, WindowHandleFor(session, surface), false)).Times(1)
2050+ .WillOnce(Return(droidinput::OK));
2051+ EXPECT_CALL(*dispatcher, setFocusedApplication(ApplicationHandleFor(session))).Times(1);
2052+ EXPECT_CALL(*dispatcher, setInputWindows(VectorContainingWindowHandleFor(session, surface))).Times(1);
2053+ EXPECT_CALL(*dispatcher, unregisterInputChannel(_)).Times(1);
2054+ EXPECT_CALL(*dispatcher, setInputWindows(EmptyVector())).Times(1);
2055+
2056+ mia::InputManager manager(mt::fake_shared(config));
2057+
2058+ manager.set_input_focus_to(session, surface);
2059+ manager.set_input_focus_to(session, std::shared_ptr<mi::SurfaceTarget>());
2060+}
2061
2062=== added file 'tests/unit-tests/input/android/test_android_input_window_handle.cpp'
2063--- tests/unit-tests/input/android/test_android_input_window_handle.cpp 1970-01-01 00:00:00 +0000
2064+++ tests/unit-tests/input/android/test_android_input_window_handle.cpp 2013-03-22 17:46:22 +0000
2065@@ -0,0 +1,89 @@
2066+/*
2067+ * Copyright © 2013 Canonical Ltd.
2068+ *
2069+ * This program is free software: you can redistribute it and/or modify
2070+ * it under the terms of the GNU General Public License version 3 as
2071+ * published by the Free Software Foundation.
2072+ *
2073+ * This program is distributed in the hope that it will be useful,
2074+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2075+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2076+ * GNU General Public License for more details.
2077+ *
2078+ * You should have received a copy of the GNU General Public License
2079+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2080+ *
2081+ * Authored by: Robert Carr <robert.carr@canonical.com>
2082+ */
2083+
2084+#include "src/server/input/android/android_input_window_handle.h"
2085+
2086+#include "mir/frontend/surface.h"
2087+#include "mir/geometry/size.h"
2088+#include "mir/input/input_channel.h"
2089+#include "mir/input/surface_target.h"
2090+
2091+#include "mir_test/fake_shared.h"
2092+#include "mir_test_doubles/mock_surface.h"
2093+#include "mir_test_doubles/stub_surface_builder.h"
2094+
2095+#include <gtest/gtest.h>
2096+#include <gmock/gmock.h>
2097+
2098+namespace mc = mir::compositor;
2099+namespace mi = mir::input;
2100+namespace mia = mi::android;
2101+namespace mf = mir::frontend;
2102+namespace geom = mir::geometry;
2103+namespace mt = mir::test;
2104+namespace mtd = mt::doubles;
2105+
2106+namespace
2107+{
2108+
2109+struct StubInputApplicationHandle : public droidinput::InputApplicationHandle
2110+{
2111+ bool updateInfo() { return true; }
2112+};
2113+
2114+struct MockSurfaceTarget : public mi::SurfaceTarget
2115+{
2116+ MOCK_CONST_METHOD0(server_input_fd, int());
2117+ MOCK_CONST_METHOD0(size, geom::Size());
2118+ MOCK_CONST_METHOD0(name, std::string());
2119+};
2120+
2121+}
2122+
2123+TEST(AndroidInputWindowHandle, update_info_uses_geometry_and_channel_from_surface)
2124+{
2125+ using namespace ::testing;
2126+
2127+ geom::Size const default_surface_size = geom::Size{geom::Width{256},
2128+ geom::Height{256}};
2129+ std::string const testing_surface_name = "Test";
2130+ int const testing_server_fd = 2;
2131+
2132+ MockSurfaceTarget surface;
2133+
2134+ EXPECT_CALL(surface, server_input_fd()).Times(1)
2135+ .WillOnce(Return(testing_server_fd));
2136+ // For now since we are just doing keyboard input we only need surface size,
2137+ // for touch/pointer events we will need a position
2138+ EXPECT_CALL(surface, size()).Times(1)
2139+ .WillOnce(Return(default_surface_size));
2140+ EXPECT_CALL(surface, name()).Times(1)
2141+ .WillOnce(Return(testing_surface_name));
2142+
2143+ mia::InputWindowHandle handle(new StubInputApplicationHandle(),
2144+ mt::fake_shared(surface));
2145+
2146+ auto info = handle.getInfo();
2147+
2148+ EXPECT_EQ(testing_surface_name, info->name);
2149+
2150+ EXPECT_EQ(testing_server_fd, info->inputChannel->getFd());
2151+
2152+ EXPECT_EQ(default_surface_size.height.as_uint32_t(), (uint32_t)(info->frameRight - info->frameLeft));
2153+ EXPECT_EQ(default_surface_size.height.as_uint32_t(), (uint32_t)(info->frameBottom - info->frameTop));
2154+}
2155
2156=== modified file 'tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp'
2157--- tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp 2013-03-13 08:09:52 +0000
2158+++ tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp 2013-03-22 17:46:22 +0000
2159@@ -44,7 +44,9 @@
2160
2161 // The policy filters ALL key events before queuing
2162 policy.interceptKeyBeforeQueueing(&ev, policy_flags);
2163- EXPECT_EQ(policy_flags, droidinput::POLICY_FLAG_FILTERED);
2164+
2165+ // If the event is unfiltered we will allow it to pass to applications
2166+ EXPECT_TRUE(policy_flags & droidinput::POLICY_FLAG_PASS_TO_USER);
2167
2168 // Android uses alternate notation...the policy returns true if the event was NOT handled (e.g. the EventFilter
2169 // returns false)
2170
2171=== modified file 'tests/unit-tests/shell/test_application_session.cpp'
2172--- tests/unit-tests/shell/test_application_session.cpp 2013-03-21 03:32:59 +0000
2173+++ tests/unit-tests/shell/test_application_session.cpp 2013-03-22 17:46:22 +0000
2174@@ -23,6 +23,7 @@
2175 #include "mir_test_doubles/mock_surface_factory.h"
2176 #include "mir_test_doubles/mock_surface.h"
2177 #include "mir_test_doubles/stub_surface_builder.h"
2178+#include "mir_test_doubles/stub_surface.h"
2179
2180 #include "src/server/shell/surface.h"
2181
2182@@ -58,6 +59,41 @@
2183 session.destroy_surface(surf);
2184 }
2185
2186+TEST(ApplicationSession, default_surface_is_first_surface)
2187+{
2188+ using namespace ::testing;
2189+
2190+ mtd::MockSurfaceFactory surface_factory;
2191+ mtd::StubSurfaceBuilder surface_builder;
2192+ {
2193+ InSequence seq;
2194+ EXPECT_CALL(surface_factory, create_surface(_)).Times(1)
2195+ .WillOnce(Return(std::make_shared<mtd::MockSurface>(mt::fake_shared(surface_builder))));
2196+ EXPECT_CALL(surface_factory, create_surface(_)).Times(1)
2197+ .WillOnce(Return(std::make_shared<mtd::MockSurface>(mt::fake_shared(surface_builder))));
2198+ EXPECT_CALL(surface_factory, create_surface(_)).Times(1)
2199+ .WillOnce(Return(std::make_shared<mtd::MockSurface>(mt::fake_shared(surface_builder))));
2200+ }
2201+
2202+ msh::ApplicationSession app_session(mt::fake_shared(surface_factory), "Foo");
2203+
2204+ mf::SurfaceCreationParameters params;
2205+ auto id1 = app_session.create_surface(params);
2206+ auto id2 = app_session.create_surface(params);
2207+ auto id3 = app_session.create_surface(params);
2208+
2209+ auto default_surf = app_session.default_surface();
2210+ EXPECT_EQ(app_session.get_surface(id1), default_surf);
2211+ app_session.destroy_surface(id1);
2212+
2213+ default_surf = app_session.default_surface();
2214+ EXPECT_EQ(app_session.get_surface(id2), default_surf);
2215+ app_session.destroy_surface(id2);
2216+
2217+ default_surf = app_session.default_surface();
2218+ EXPECT_EQ(app_session.get_surface(id3), default_surf);
2219+ app_session.destroy_surface(id3);
2220+}
2221
2222 TEST(ApplicationSession, session_visbility_propagates_to_surfaces)
2223 {
2224
2225=== modified file 'tests/unit-tests/shell/test_registration_order_focus_sequence.cpp'
2226--- tests/unit-tests/shell/test_registration_order_focus_sequence.cpp 2013-03-21 03:32:59 +0000
2227+++ tests/unit-tests/shell/test_registration_order_focus_sequence.cpp 2013-03-22 17:46:22 +0000
2228@@ -18,7 +18,7 @@
2229
2230 #include "mir/surfaces/buffer_bundle.h"
2231 #include "mir/shell/application_session.h"
2232-#include "mir/frontend/session_container.h"
2233+#include "mir/shell/session_container.h"
2234 #include "mir/shell/registration_order_focus_sequence.h"
2235 #include "mir/frontend/surface_creation_parameters.h"
2236 #include "mir/surfaces/surface.h"
2237
2238=== modified file 'tests/unit-tests/shell/test_session_manager.cpp'
2239--- tests/unit-tests/shell/test_session_manager.cpp 2013-03-21 03:32:59 +0000
2240+++ tests/unit-tests/shell/test_session_manager.cpp 2013-03-22 17:46:22 +0000
2241@@ -17,11 +17,12 @@
2242 */
2243
2244 #include "mir/surfaces/buffer_bundle.h"
2245+#include "mir/shell/focus_sequence.h"
2246 #include "mir/shell/session_manager.h"
2247-#include "mir/frontend/session_container.h"
2248+#include "mir/shell/session_container.h"
2249+#include "mir/shell/session.h"
2250 #include "mir/frontend/session.h"
2251 #include "mir/frontend/surface_creation_parameters.h"
2252-#include "mir/shell/focus_sequence.h"
2253 #include "mir/surfaces/surface.h"
2254 #include "mir/input/input_channel.h"
2255 #include "mir_test_doubles/mock_buffer_bundle.h"
2256@@ -90,7 +91,7 @@
2257 EXPECT_CALL(container, insert_session(_)).Times(1);
2258 EXPECT_CALL(container, remove_session(_)).Times(1);
2259 EXPECT_CALL(focus_setter, set_focus_to(_));
2260- EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<mf::Session>())).Times(1);
2261+ EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<msh::Session>())).Times(1);
2262
2263 EXPECT_CALL(sequence, default_focus()).WillOnce(Return((std::shared_ptr<mf::Session>())));
2264
2265@@ -115,7 +116,7 @@
2266 EXPECT_CALL(container, remove_session(_)).Times(1);
2267
2268 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(1);
2269- EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<mf::Session>())).Times(1);
2270+ EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<msh::Session>())).Times(1);
2271
2272 EXPECT_CALL(sequence, default_focus()).WillOnce(Return((std::shared_ptr<mf::Session>())));
2273
2274@@ -146,7 +147,7 @@
2275
2276 session_manager.tag_session_with_lightdm_id(session1, 1);
2277
2278- EXPECT_CALL(focus_setter, set_focus_to(session1));
2279+ EXPECT_CALL(focus_setter, set_focus_to(Eq(session1)));
2280 session_manager.focus_session_with_lightdm_id(1);
2281 }
2282
2283@@ -161,7 +162,7 @@
2284 session_manager.focus_session_with_lightdm_id(1);
2285
2286 EXPECT_CALL(sequence, default_focus()).WillOnce(Return(session2));
2287- EXPECT_CALL(focus_setter, set_focus_to(session2));
2288+ EXPECT_CALL(focus_setter, set_focus_to(Eq(session2)));
2289
2290 session_manager.close_session(session1);
2291 }
2292
2293=== modified file 'tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp'
2294--- tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp 2013-03-21 03:32:59 +0000
2295+++ tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp 2013-03-22 17:46:22 +0000
2296@@ -18,15 +18,19 @@
2297
2298 #include "mir/surfaces/buffer_bundle.h"
2299 #include "mir/shell/application_session.h"
2300-#include "mir/frontend/session_container.h"
2301+#include "mir/shell/session_container.h"
2302 #include "mir/shell/registration_order_focus_sequence.h"
2303 #include "mir/shell/single_visibility_focus_mechanism.h"
2304+#include "mir/shell/session.h"
2305 #include "mir/frontend/surface_creation_parameters.h"
2306 #include "mir/surfaces/surface.h"
2307 #include "mir_test_doubles/mock_buffer_bundle.h"
2308 #include "mir_test/fake_shared.h"
2309 #include "mir_test_doubles/mock_surface_factory.h"
2310-#include "mir_test_doubles/mock_session.h"
2311+#include "mir_test_doubles/mock_input_focus_selector.h"
2312+#include "mir_test_doubles/stub_surface.h"
2313+#include "mir_test_doubles/mock_surface.h"
2314+#include "mir_test_doubles/stub_surface_builder.h"
2315
2316 #include <gmock/gmock.h>
2317 #include <gtest/gtest.h>
2318@@ -35,19 +39,41 @@
2319 namespace mc = mir::compositor;
2320 namespace msh = mir::shell;
2321 namespace ms = mir::surfaces;
2322+namespace mf = mir::frontend;
2323 namespace mt = mir::test;
2324 namespace mtd = mir::test::doubles;
2325
2326+struct MockShellSession : public msh::Session
2327+{
2328+ MOCK_METHOD1(create_surface, mf::SurfaceId(mf::SurfaceCreationParameters const&));
2329+ MOCK_METHOD1(destroy_surface, void(mf::SurfaceId));
2330+ MOCK_CONST_METHOD1(get_surface, std::shared_ptr<mf::Surface>(mf::SurfaceId));
2331+
2332+ MOCK_CONST_METHOD0(default_surface, std::shared_ptr<msh::Surface>());
2333+
2334+ MOCK_CONST_METHOD0(name, std::string());
2335+ MOCK_METHOD0(shutdown, void());
2336+
2337+ MOCK_METHOD0(hide, void());
2338+ MOCK_METHOD0(show, void());
2339+
2340+ MOCK_METHOD3(configure_surface, int(mf::SurfaceId, MirSurfaceAttrib, int));
2341+};
2342+
2343 TEST(SingleVisibilityFocusMechanism, mechanism_sets_visibility)
2344 {
2345 using namespace ::testing;
2346
2347- mtd::MockSession app1;
2348- mtd::MockSession app2;
2349- mtd::MockSession app3;
2350+ NiceMock<mtd::MockInputFocusSelector> input_focus_selector;
2351
2352+ MockShellSession app1, app2, app3;
2353 msh::SessionContainer model;
2354- msh::SingleVisibilityFocusMechanism focus_mechanism(mt::fake_shared(model));
2355+
2356+ ON_CALL(app1, default_surface()).WillByDefault(Return(std::shared_ptr<msh::Surface>()));
2357+ ON_CALL(app2, default_surface()).WillByDefault(Return(std::shared_ptr<msh::Surface>()));
2358+ ON_CALL(app3, default_surface()).WillByDefault(Return(std::shared_ptr<msh::Surface>()));
2359+
2360+ msh::SingleVisibilityFocusMechanism focus_mechanism(mt::fake_shared(model), mt::fake_shared(input_focus_selector));
2361
2362 EXPECT_CALL(app1, show()).Times(1);
2363 EXPECT_CALL(app2, hide()).Times(1);
2364@@ -60,3 +86,22 @@
2365 focus_mechanism.set_focus_to(mt::fake_shared(app1));
2366 }
2367
2368+TEST(SingleVisibilityFocusMechanism, mechanism_sets_input_focus_from_default_surface)
2369+{
2370+ using namespace ::testing;
2371+
2372+ mtd::MockInputFocusSelector input_focus_selector;
2373+ msh::SessionContainer model;
2374+ auto session = std::make_shared<MockShellSession>();
2375+ auto surface = std::make_shared<mtd::MockSurface>(std::make_shared<mtd::StubSurfaceBuilder>());
2376+
2377+ msh::SingleVisibilityFocusMechanism focus_mechanism(mt::fake_shared(model), mt::fake_shared(input_focus_selector));
2378+
2379+ EXPECT_CALL(*session, default_surface()).Times(1).WillOnce(Return(surface));
2380+
2381+ EXPECT_CALL(input_focus_selector, set_input_focus_to(Eq(session), Eq(surface))).Times(1);
2382+
2383+ model.insert_session(session);
2384+ focus_mechanism.set_focus_to(session);
2385+}
2386+
2387
2388=== modified file 'tests/unit-tests/shell/test_surface.cpp'
2389--- tests/unit-tests/shell/test_surface.cpp 2013-03-21 03:55:40 +0000
2390+++ tests/unit-tests/shell/test_surface.cpp 2013-03-22 17:46:22 +0000
2391@@ -178,6 +178,24 @@
2392 }, std::runtime_error);
2393 }
2394
2395+TEST_F(ShellSurface, name_throw_behavior)
2396+{
2397+ msh::Surface test(
2398+ mt::fake_shared(surface_builder),
2399+ mf::a_surface(),
2400+ null_input_channel);
2401+
2402+ EXPECT_NO_THROW({
2403+ test.name();
2404+ });
2405+
2406+ surface_builder.reset_surface();
2407+
2408+ EXPECT_THROW({
2409+ test.name();
2410+ }, std::runtime_error);
2411+}
2412+
2413 TEST_F(ShellSurface, pixel_format_throw_behavior)
2414 {
2415 msh::Surface test(
2416
2417=== modified file 'tests/unit-tests/shell/test_the_session_container_implementation.cpp'
2418--- tests/unit-tests/shell/test_the_session_container_implementation.cpp 2013-03-21 03:32:59 +0000
2419+++ tests/unit-tests/shell/test_the_session_container_implementation.cpp 2013-03-22 17:46:22 +0000
2420@@ -18,7 +18,7 @@
2421
2422 #include "mir/surfaces/buffer_bundle.h"
2423 #include "mir/shell/application_session.h"
2424-#include "mir/frontend/session_container.h"
2425+#include "mir/shell/session_container.h"
2426 #include "mir/frontend/surface_creation_parameters.h"
2427 #include "mir/surfaces/surface.h"
2428 #include "mir_test_doubles/mock_buffer_bundle.h"

Subscribers

People subscribed via source and target branches