Mir

Merge lp:~robertcarr/mir/enable-pointer-touch-input into lp:~mir-team/mir/trunk

Proposed by Robert Carr
Status: Superseded
Proposed branch: lp:~robertcarr/mir/enable-pointer-touch-input
Merge into: lp:~mir-team/mir/trunk
Diff against target: 2645 lines (+1013/-387)
49 files modified
include/server/mir/default_server_configuration.h (+3/-3)
include/server/mir/input/input_manager.h (+0/-1)
include/server/mir/input/null_input_manager.h (+0/-5)
include/server/mir/input/null_input_target_listener.h (+26/-11)
include/server/mir/input/surface_target.h (+2/-0)
include/server/mir/shell/application_session.h (+4/-1)
include/server/mir/shell/input_focus_selector.h (+0/-52)
include/server/mir/shell/input_target_listener.h (+59/-0)
include/server/mir/shell/session_manager.h (+5/-2)
include/server/mir/shell/single_visibility_focus_mechanism.h (+1/-4)
include/server/mir/shell/surface.h (+1/-0)
include/test/mir_test/event_matchers.h (+64/-0)
include/test/mir_test/fake_event_hub_input_configuration.h (+2/-0)
include/test/mir_test_doubles/mock_event_filter.h (+0/-32)
include/test/mir_test_doubles/mock_input_focus_selector.h (+0/-40)
include/test/mir_test_doubles/mock_input_target_listener.h (+49/-0)
include/test/mir_test_doubles/stub_input_target_listener.h (+59/-0)
include/test/mir_test_doubles/stub_surface_target.h (+4/-0)
include/test/mir_test_framework/testing_server_configuration.h (+1/-1)
src/server/default_server_configuration.cpp (+8/-8)
src/server/display_server.cpp (+1/-1)
src/server/input/android/android_dispatcher_controller.cpp (+73/-23)
src/server/input/android/android_dispatcher_controller.h (+19/-6)
src/server/input/android/android_input_window_handle.cpp (+8/-2)
src/server/input/android/default_android_input_configuration.cpp (+6/-1)
src/server/input/android/default_android_input_configuration.h (+2/-0)
src/server/input/android/event_filter_dispatcher_policy.cpp (+6/-5)
src/server/input/android/event_filter_dispatcher_policy.h (+2/-1)
src/server/shell/application_session.cpp (+6/-2)
src/server/shell/session_manager.cpp (+27/-10)
src/server/shell/single_visibility_focus_mechanism.cpp (+2/-7)
src/server/shell/surface.cpp (+12/-0)
tests/acceptance-tests/test_client_input.cpp (+145/-35)
tests/acceptance-tests/test_focus_selection.cpp (+21/-21)
tests/death-tests/test_application_manager_death.cpp (+4/-3)
tests/integration-tests/input/android/test_android_input_manager.cpp (+71/-12)
tests/integration-tests/input/android/test_fake_event_hub_to_event_filter.cpp (+2/-1)
tests/integration-tests/shell/test_session_manager.cpp (+24/-17)
tests/mir_test_doubles/fake_event_hub.cpp (+2/-2)
tests/mir_test_framework/testing_server_options.cpp (+3/-11)
tests/unit-tests/input/android/test_android_dispatcher_controller.cpp (+138/-13)
tests/unit-tests/input/android/test_android_input_window_handle.cpp (+11/-0)
tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp (+15/-2)
tests/unit-tests/shell/test_application_session.cpp (+11/-5)
tests/unit-tests/shell/test_registration_order_focus_sequence.cpp (+16/-11)
tests/unit-tests/shell/test_session_manager.cpp (+72/-8)
tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp (+1/-24)
tests/unit-tests/shell/test_surface.cpp (+18/-0)
tests/unit-tests/shell/test_the_session_container_implementation.cpp (+7/-4)
To merge this branch: bzr merge lp:~robertcarr/mir/enable-pointer-touch-input
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+160151@code.launchpad.net

This proposal has been superseded by a proposal from 2013-04-22.

Commit message

Enable motion events! (Pointer and touch input)

Description of the change

Enable motion events in the DispatcherPolicy and Window Handle. This branch is largely new acceptance tests! (small changes to event_filter_dispatcher_policy and android_input_window_handle)

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/server/mir/default_server_configuration.h'
--- include/server/mir/default_server_configuration.h 2013-04-19 15:59:41 +0000
+++ include/server/mir/default_server_configuration.h 2013-04-22 16:32:37 +0000
@@ -50,7 +50,7 @@
50{50{
51class SurfaceFactory;51class SurfaceFactory;
52class SurfaceBuilder;52class SurfaceBuilder;
53class InputFocusSelector;53class InputTargetListener;
54class SessionContainer;54class SessionContainer;
55class FocusSetter;55class FocusSetter;
56class FocusSequence;56class FocusSequence;
@@ -156,7 +156,6 @@
156 /** @name shell configuration - dependencies156 /** @name shell configuration - dependencies
157 * dependencies of shell on the rest of the Mir157 * dependencies of shell on the rest of the Mir
158 * @{ */158 * @{ */
159 virtual std::shared_ptr<shell::InputFocusSelector> the_input_focus_selector();
160 virtual std::shared_ptr<shell::SurfaceBuilder> the_surface_builder();159 virtual std::shared_ptr<shell::SurfaceBuilder> the_surface_builder();
161 /** @} */160 /** @} */
162161
@@ -178,6 +177,7 @@
178 * @{ */177 * @{ */
179 virtual std::shared_ptr<input::android::InputConfiguration> the_input_configuration();178 virtual std::shared_ptr<input::android::InputConfiguration> the_input_configuration();
180 virtual std::initializer_list<std::shared_ptr<input::EventFilter> const> the_event_filters();179 virtual std::initializer_list<std::shared_ptr<input::EventFilter> const> the_event_filters();
180 virtual std::shared_ptr<shell::InputTargetListener> the_input_target_listener();
181 /** @} */181 /** @} */
182182
183 /** @name logging configuration - customization183 /** @name logging configuration - customization
@@ -197,7 +197,7 @@
197 CachedPtr<frontend::Shell> session_manager;197 CachedPtr<frontend::Shell> session_manager;
198 std::shared_ptr<input::android::InputConfiguration> input_configuration;198 std::shared_ptr<input::android::InputConfiguration> input_configuration;
199 CachedPtr<input::InputManager> input_manager;199 CachedPtr<input::InputManager> input_manager;
200 CachedPtr<shell::InputFocusSelector> input_focus_selector;200 CachedPtr<shell::InputTargetListener> input_target_listener;
201 CachedPtr<graphics::Platform> graphics_platform;201 CachedPtr<graphics::Platform> graphics_platform;
202 CachedPtr<graphics::BufferInitializer> buffer_initializer;202 CachedPtr<graphics::BufferInitializer> buffer_initializer;
203 CachedPtr<compositor::GraphicBufferAllocator> buffer_allocator;203 CachedPtr<compositor::GraphicBufferAllocator> buffer_allocator;
204204
=== modified file 'include/server/mir/input/input_manager.h'
--- include/server/mir/input/input_manager.h 2013-04-16 09:08:29 +0000
+++ include/server/mir/input/input_manager.h 2013-04-22 16:32:37 +0000
@@ -21,7 +21,6 @@
21#define MIR_INPUT_INPUT_MANAGER_H_21#define MIR_INPUT_INPUT_MANAGER_H_
2222
23#include "mir/input/input_channel_factory.h"23#include "mir/input/input_channel_factory.h"
24#include "mir/shell/input_focus_selector.h"
2524
26#include <memory>25#include <memory>
2726
2827
=== modified file 'include/server/mir/input/null_input_manager.h'
--- include/server/mir/input/null_input_manager.h 2013-04-16 09:08:29 +0000
+++ include/server/mir/input/null_input_manager.h 2013-04-22 16:32:37 +0000
@@ -40,11 +40,6 @@
40 return std::shared_ptr<InputChannel>();40 return std::shared_ptr<InputChannel>();
41 }41 }
4242
43 virtual void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& /* session */,
44 std::shared_ptr<input::SurfaceTarget> const& /* surface */)
45 {
46 }
47
48protected:43protected:
49 NullInputManager(const NullInputManager&) = delete;44 NullInputManager(const NullInputManager&) = delete;
50 NullInputManager& operator=(const NullInputManager&) = delete;45 NullInputManager& operator=(const NullInputManager&) = delete;
5146
=== renamed file 'include/server/mir/input/null_input_focus_selector.h' => 'include/server/mir/input/null_input_target_listener.h'
--- include/server/mir/input/null_input_focus_selector.h 2013-04-17 02:04:35 +0000
+++ include/server/mir/input/null_input_target_listener.h 2013-04-22 16:32:37 +0000
@@ -16,33 +16,48 @@
16 * Authored by: Robert Carr <robert.carr@canonical.com>16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */17 */
1818
19#ifndef MIR_INPUT_NULL_INPUT_FOCUS_SELECTOR_H_19#ifndef MIR_INPUT_NULL_INPUT_TARGET_LISTENER_H_
20#define MIR_INPUT_NULL_INPUT_FOCUS_SELECTOR_H_20#define MIR_INPUT_NULL_INPUT_TARGET_LISTENER_H_
2121
22#include "mir/shell/input_focus_selector.h"22#include "mir/shell/input_target_listener.h"
2323
24namespace mir24namespace mir
25{25{
26namespace input26namespace input
27{27{
2828
29class NullInputFocusSelector : public shell::InputFocusSelector29class NullInputTargetListener : public shell::InputTargetListener
30{30{
31public:31public:
32 NullInputFocusSelector() {};32 NullInputTargetListener() {};
33 virtual ~NullInputFocusSelector() {}33 virtual ~NullInputTargetListener() noexcept(true) {}
34 34
35 virtual void set_input_focus_to(std::shared_ptr<input::SessionTarget> const&,35 virtual void input_application_opened(std::shared_ptr<input::SessionTarget> const&)
36 std::shared_ptr<input::SurfaceTarget> const&)36 {
37 }
38 virtual void input_application_closed(std::shared_ptr<input::SessionTarget> const&)
39 {
40 }
41 virtual void input_surface_opened(std::shared_ptr<input::SessionTarget> const&,
42 std::shared_ptr<input::SurfaceTarget> const&)
43 {
44 }
45 virtual void input_surface_closed(std::shared_ptr<input::SurfaceTarget> const&)
46 {
47 }
48 virtual void focus_changed(std::shared_ptr<input::SurfaceTarget> const&)
49 {
50 }
51 virtual void focus_cleared()
37 {52 {
38 }53 }
3954
40protected:55protected:
41 NullInputFocusSelector(const NullInputFocusSelector&) = delete;56 NullInputTargetListener(const NullInputTargetListener&) = delete;
42 NullInputFocusSelector& operator=(const NullInputFocusSelector&) = delete;57 NullInputTargetListener& operator=(const NullInputTargetListener&) = delete;
43};58};
4459
45}60}
46}61}
4762
48#endif // MIR_INPUT_NULL_INPUT_FOCUS_SELECTOR_H_63#endif // MIR_INPUT_NULL_INPUT_TARGET_LISTENER_H_
4964
=== modified file 'include/server/mir/input/surface_target.h'
--- include/server/mir/input/surface_target.h 2013-04-16 09:08:29 +0000
+++ include/server/mir/input/surface_target.h 2013-04-22 16:32:37 +0000
@@ -20,6 +20,7 @@
20#define MIR_INPUT_SURFACE_TARGET_H_20#define MIR_INPUT_SURFACE_TARGET_H_
2121
22#include "mir/geometry/size.h"22#include "mir/geometry/size.h"
23#include "mir/geometry/point.h"
2324
24#include <string>25#include <string>
2526
@@ -33,6 +34,7 @@
33public:34public:
34 virtual ~SurfaceTarget() {}35 virtual ~SurfaceTarget() {}
3536
37 virtual geometry::Point top_left() const = 0;
36 virtual geometry::Size size() const = 0;38 virtual geometry::Size size() const = 0;
37 virtual std::string name() const = 0;39 virtual std::string name() const = 0;
3840
3941
=== modified file 'include/server/mir/shell/application_session.h'
--- include/server/mir/shell/application_session.h 2013-04-16 17:42:26 +0000
+++ include/server/mir/shell/application_session.h 2013-04-22 16:32:37 +0000
@@ -30,11 +30,13 @@
30{30{
31class SurfaceFactory;31class SurfaceFactory;
32class Surface;32class Surface;
33class InputTargetListener;
3334
34class ApplicationSession : public Session35class ApplicationSession : public Session
35{36{
36public:37public:
37 explicit ApplicationSession(std::shared_ptr<SurfaceFactory> const& surface_factory, std::string const& session_name);38 explicit ApplicationSession(std::shared_ptr<SurfaceFactory> const& surface_factory,
39 std::shared_ptr<InputTargetListener> const& input_target_listener, std::string const& session_name);
38 ~ApplicationSession();40 ~ApplicationSession();
3941
40 frontend::SurfaceId create_surface(frontend::SurfaceCreationParameters const& params);42 frontend::SurfaceId create_surface(frontend::SurfaceCreationParameters const& params);
@@ -58,6 +60,7 @@
5860
59private:61private:
60 std::shared_ptr<SurfaceFactory> const surface_factory;62 std::shared_ptr<SurfaceFactory> const surface_factory;
63 std::shared_ptr<InputTargetListener> const input_target_listener;
61 std::string const session_name;64 std::string const session_name;
6265
63 frontend::SurfaceId next_id();66 frontend::SurfaceId next_id();
6467
=== removed file 'include/server/mir/shell/input_focus_selector.h'
--- include/server/mir/shell/input_focus_selector.h 2013-04-16 09:08:29 +0000
+++ include/server/mir/shell/input_focus_selector.h 1970-01-01 00:00:00 +0000
@@ -1,52 +0,0 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#ifndef MIR_SHELL_INPUT_FOCUS_SELECTOR_H_
20#define MIR_SHELL_INPUT_FOCUS_SELECTOR_H_
21
22#include <memory>
23
24namespace mir
25{
26namespace input
27{
28class SessionTarget;
29class SurfaceTarget;
30}
31
32namespace shell
33{
34
35class InputFocusSelector
36{
37public:
38 virtual ~InputFocusSelector() {}
39
40 virtual void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& focus_application,
41 std::shared_ptr<input::SurfaceTarget> const& focus_surface) = 0;
42
43protected:
44 InputFocusSelector() = default;
45 InputFocusSelector(InputFocusSelector const&) = delete;
46 InputFocusSelector& operator=(InputFocusSelector const&) = delete;
47};
48
49}
50} // namespace mir
51
52#endif // MIR_SHELL_INPUT_FOCUS_SELECTOR_H_
530
=== added file 'include/server/mir/shell/input_target_listener.h'
--- include/server/mir/shell/input_target_listener.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/shell/input_target_listener.h 2013-04-22 16:32:37 +0000
@@ -0,0 +1,59 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#ifndef MIR_SHELL_INPUT_TARGET_LISTENER_H_
20#define MIR_SHELL_INPUT_TARGET_LISTENER_H_
21
22#include <memory>
23
24namespace mir
25{
26namespace input
27{
28class SessionTarget;
29class SurfaceTarget;
30}
31
32namespace shell
33{
34
35class InputTargetListener
36{
37public:
38 virtual ~InputTargetListener() = default;
39
40 virtual void input_application_opened(std::shared_ptr<input::SessionTarget> const& application) = 0;
41 virtual void input_application_closed(std::shared_ptr<input::SessionTarget> const& application) = 0;
42
43 virtual void input_surface_opened(std::shared_ptr<input::SessionTarget> const& application,
44 std::shared_ptr<input::SurfaceTarget> const& opened_surface) = 0;
45 virtual void input_surface_closed(std::shared_ptr<input::SurfaceTarget> const& closed_surface) = 0;
46
47 virtual void focus_changed(std::shared_ptr<input::SurfaceTarget> const& focus_surface) = 0;
48 virtual void focus_cleared() = 0;
49
50protected:
51 InputTargetListener() = default;
52 InputTargetListener(InputTargetListener const&) = delete;
53 InputTargetListener& operator=(InputTargetListener const&) = delete;
54};
55
56}
57} // namespace mir
58
59#endif // MIR_SHELL_INPUT_TARGET_LISTENER_H_
060
=== modified file 'include/server/mir/shell/session_manager.h'
--- include/server/mir/shell/session_manager.h 2013-04-19 09:15:31 +0000
+++ include/server/mir/shell/session_manager.h 2013-04-22 16:32:37 +0000
@@ -40,15 +40,17 @@
40class SessionContainer;40class SessionContainer;
41class FocusSequence;41class FocusSequence;
42class FocusSetter;42class FocusSetter;
43class InputTargetListener;
43class Session;44class Session;
4445
45class SessionManager : public frontend::Shell46class SessionManager : public frontend::Shell
46{47{
47public:48public:
48 explicit SessionManager(std::shared_ptr<SurfaceFactory> const& surface_factory,49 explicit SessionManager(std::shared_ptr<SurfaceFactory> const& surface_factory,
49 std::shared_ptr<SessionContainer> const& session_container,50 std::shared_ptr<SessionContainer> const& app_container,
50 std::shared_ptr<FocusSequence> const& focus_sequence,51 std::shared_ptr<FocusSequence> const& focus_sequence,
51 std::shared_ptr<FocusSetter> const& focus_setter);52 std::shared_ptr<FocusSetter> const& focus_setter,
53 std::shared_ptr<InputTargetListener> const& input_target_listener);
52 virtual ~SessionManager();54 virtual ~SessionManager();
5355
54 virtual std::shared_ptr<frontend::Session> open_session(std::string const& name);56 virtual std::shared_ptr<frontend::Session> open_session(std::string const& name);
@@ -71,6 +73,7 @@
71 std::shared_ptr<SessionContainer> const app_container;73 std::shared_ptr<SessionContainer> const app_container;
72 std::shared_ptr<FocusSequence> const focus_sequence;74 std::shared_ptr<FocusSequence> const focus_sequence;
73 std::shared_ptr<FocusSetter> const focus_setter;75 std::shared_ptr<FocusSetter> const focus_setter;
76 std::shared_ptr<InputTargetListener> const input_target_listener;
7477
75 std::mutex mutex;78 std::mutex mutex;
76 std::weak_ptr<Session> focus_application;79 std::weak_ptr<Session> focus_application;
7780
=== modified file 'include/server/mir/shell/single_visibility_focus_mechanism.h'
--- include/server/mir/shell/single_visibility_focus_mechanism.h 2013-04-16 09:08:29 +0000
+++ include/server/mir/shell/single_visibility_focus_mechanism.h 2013-04-22 16:32:37 +0000
@@ -28,13 +28,11 @@
28namespace shell28namespace shell
29{29{
30class SessionContainer;30class SessionContainer;
31class InputFocusSelector;
3231
33class SingleVisibilityFocusMechanism : public FocusSetter32class SingleVisibilityFocusMechanism : public FocusSetter
34{33{
35public:34public:
36 explicit SingleVisibilityFocusMechanism(std::shared_ptr<SessionContainer> const& app_container,35 explicit SingleVisibilityFocusMechanism(std::shared_ptr<SessionContainer> const& app_container);
37 std::shared_ptr<shell::InputFocusSelector> const& input_selector);
38 virtual ~SingleVisibilityFocusMechanism() {}36 virtual ~SingleVisibilityFocusMechanism() {}
3937
40 void set_focus_to(std::shared_ptr<shell::Session> const& new_focus);38 void set_focus_to(std::shared_ptr<shell::Session> const& new_focus);
@@ -44,7 +42,6 @@
44 SingleVisibilityFocusMechanism& operator=(const SingleVisibilityFocusMechanism&) = delete;42 SingleVisibilityFocusMechanism& operator=(const SingleVisibilityFocusMechanism&) = delete;
45private:43private:
46 std::shared_ptr<SessionContainer> const app_container;44 std::shared_ptr<SessionContainer> const app_container;
47 std::shared_ptr<shell::InputFocusSelector> const input_selector;
48};45};
4946
50}47}
5148
=== modified file 'include/server/mir/shell/surface.h'
--- include/server/mir/shell/surface.h 2013-04-16 17:42:26 +0000
+++ include/server/mir/shell/surface.h 2013-04-22 16:32:37 +0000
@@ -63,6 +63,7 @@
63 virtual std::string name() const;63 virtual std::string name() const;
6464
65 virtual geometry::Size size() const;65 virtual geometry::Size size() const;
66 virtual geometry::Point top_left() const;
6667
67 virtual geometry::PixelFormat pixel_format() const;68 virtual geometry::PixelFormat pixel_format() const;
6869
6970
=== added file 'include/test/mir_test/event_matchers.h'
--- include/test/mir_test/event_matchers.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test/event_matchers.h 2013-04-22 16:32:37 +0000
@@ -0,0 +1,64 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#ifndef MIR_TEST_EVENT_MATCHERS_H_
20#define MIR_TEST_EVENT_MATCHERS_H_
21
22#include <androidfw/Input.h>
23
24#include <gmock/gmock.h>
25
26namespace mir
27{
28namespace test
29{
30
31MATCHER_P(IsKeyEventWithKey, key, "")
32{
33 if (arg.type != mir_event_type_key)
34 return false;
35
36 return arg.key.key_code == key;
37}
38MATCHER(KeyDownEvent, "")
39{
40 if (arg.type != mir_event_type_key)
41 return false;
42
43 return arg.key.action == AKEY_EVENT_ACTION_DOWN;
44}
45MATCHER(ButtonDownEvent, "")
46{
47 if (arg.type != mir_event_type_motion)
48 return false;
49 if (arg.motion.button_state == 0)
50 return false;
51 return arg.motion.action == AMOTION_EVENT_ACTION_DOWN;
52}
53MATCHER_P2(MotionEvent, dx, dy, "")
54{
55 if (arg.type != mir_event_type_motion)
56 return false;
57 auto coords = &arg.motion.pointer_coordinates[0];
58 return (coords->x == dx) && (coords->y == dy);
59}
60
61}
62} // namespace mir
63
64#endif // MIR_TEST_EVENT_MATCHERS_H_
065
=== modified file 'include/test/mir_test/fake_event_hub_input_configuration.h'
--- include/test/mir_test/fake_event_hub_input_configuration.h 2013-04-16 09:08:29 +0000
+++ include/test/mir_test/fake_event_hub_input_configuration.h 2013-04-22 16:32:37 +0000
@@ -63,6 +63,8 @@
6363
64 droidinput::sp<droidinput::EventHubInterface> the_event_hub();64 droidinput::sp<droidinput::EventHubInterface> the_event_hub();
65 input::android::FakeEventHub* the_fake_event_hub();65 input::android::FakeEventHub* the_fake_event_hub();
66
67 bool is_key_repeat_enabled() override { return false; }
6668
6769
68protected:70protected:
6971
=== modified file 'include/test/mir_test_doubles/mock_event_filter.h'
--- include/test/mir_test_doubles/mock_event_filter.h 2013-04-16 09:08:29 +0000
+++ include/test/mir_test_doubles/mock_event_filter.h 2013-04-22 16:32:37 +0000
@@ -21,8 +21,6 @@
2121
22#include "mir/input/event_filter.h"22#include "mir/input/event_filter.h"
2323
24#include <androidfw/Input.h>
25
26#include <gmock/gmock.h>24#include <gmock/gmock.h>
2725
28namespace mir26namespace mir
@@ -36,36 +34,6 @@
36 MOCK_METHOD1(handles, bool(const MirEvent&));34 MOCK_METHOD1(handles, bool(const MirEvent&));
37};35};
38}36}
39
40MATCHER_P(IsKeyEventWithKey, key, "")
41{
42 if (arg.type != mir_event_type_key)
43 return false;
44
45 return arg.key.key_code == key;
46}
47MATCHER(KeyDownEvent, "")
48{
49 if (arg.type != mir_event_type_key)
50 return false;
51
52 return arg.key.action == AKEY_EVENT_ACTION_DOWN;
53}
54MATCHER(ButtonDownEvent, "")
55{
56 if (arg.type != mir_event_type_motion)
57 return false;
58 if (arg.motion.button_state == 0)
59 return false;
60 return arg.motion.action == AKEY_EVENT_ACTION_DOWN;
61}
62MATCHER_P2(MotionEvent, dx, dy, "")
63{
64 if (arg.type != mir_event_type_motion)
65 return false;
66 auto coords = &arg.motion.pointer_coordinates[0];
67 return (coords->x == dx) && (coords->y == dy);
68}
69}37}
70}38}
7139
7240
=== removed file 'include/test/mir_test_doubles/mock_input_focus_selector.h'
--- include/test/mir_test_doubles/mock_input_focus_selector.h 2013-04-16 09:08:29 +0000
+++ include/test/mir_test_doubles/mock_input_focus_selector.h 1970-01-01 00:00:00 +0000
@@ -1,40 +0,0 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_FOCUS_SELECTOR_H_
20#define MIR_TEST_DOUBLES_MOCK_INPUT_FOCUS_SELECTOR_H_
21
22#include "mir/shell/input_focus_selector.h"
23
24namespace mir
25{
26namespace test
27{
28namespace doubles
29{
30
31struct MockInputFocusSelector : public shell::InputFocusSelector
32{
33 MOCK_METHOD2(set_input_focus_to, void(std::shared_ptr<input::SessionTarget> const&, std::shared_ptr<input::SurfaceTarget> const&));
34};
35
36}
37}
38} // namespace mir
39
40#endif // MIR_TEST_DOUBLES_MOCK_INPUT_FOCUS_SELECTOR_H_
410
=== added file 'include/test/mir_test_doubles/mock_input_target_listener.h'
--- include/test/mir_test_doubles/mock_input_target_listener.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test_doubles/mock_input_target_listener.h 2013-04-22 16:32:37 +0000
@@ -0,0 +1,49 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_TARGET_LISTENER_H_
20#define MIR_TEST_DOUBLES_MOCK_INPUT_TARGET_LISTENER_H_
21
22#include "mir/shell/input_target_listener.h"
23
24#include <gmock/gmock.h>
25
26namespace mir
27{
28namespace test
29{
30namespace doubles
31{
32
33struct MockInputTargetListener : public shell::InputTargetListener
34{
35 virtual ~MockInputTargetListener() noexcept(true) {}
36 MOCK_METHOD1(input_application_opened, void(std::shared_ptr<input::SessionTarget> const& application));
37 MOCK_METHOD1(input_application_closed, void(std::shared_ptr<input::SessionTarget> const& application));
38 MOCK_METHOD2(input_surface_opened, void(std::shared_ptr<input::SessionTarget> const& application,
39 std::shared_ptr<input::SurfaceTarget> const& opened_surface));
40 MOCK_METHOD1(input_surface_closed, void(std::shared_ptr<input::SurfaceTarget> const& closed_surface));
41 MOCK_METHOD1(focus_changed, void(std::shared_ptr<input::SurfaceTarget> const& focus_surface));
42 MOCK_METHOD0(focus_cleared, void());
43};
44
45}
46}
47} // namespace mir
48
49#endif // MIR_TEST_DOUBLES_MOCK_INPUT_TARGET_LISTENER_H_
050
=== added file 'include/test/mir_test_doubles/stub_input_target_listener.h'
--- include/test/mir_test_doubles/stub_input_target_listener.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test_doubles/stub_input_target_listener.h 2013-04-22 16:32:37 +0000
@@ -0,0 +1,59 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#ifndef MIR_TEST_DOUBLES_STUB_INPUT_LISTENER_H_
20#define MIR_TEST_DOUBLES_STUB_INPUT_LISTENER_H_
21
22#include "mir/shell/input_target_listener.h"
23
24namespace mir
25{
26namespace test
27{
28namespace doubles
29{
30
31struct StubInputTargetListener : public shell::InputTargetListener
32{
33 void input_application_opened(std::shared_ptr<input::SessionTarget> const&)
34 {
35 }
36 void input_application_closed(std::shared_ptr<input::SessionTarget> const&)
37 {
38 }
39 void input_surface_opened(std::shared_ptr<input::SessionTarget> const&,
40 std::shared_ptr<input::SurfaceTarget> const&)
41 {
42 }
43 void input_surface_closed(std::shared_ptr<input::SurfaceTarget> const&)
44 {
45 }
46 void focus_changed(std::shared_ptr<input::SurfaceTarget> const&)
47 {
48 }
49
50 void focus_cleared()
51 {
52 }
53};
54
55}
56}
57} // namespace mir
58
59#endif // MIR_TEST_DOUBLES_STUB_INPUT_LISTENER_H_
060
=== modified file 'include/test/mir_test_doubles/stub_surface_target.h'
--- include/test/mir_test_doubles/stub_surface_target.h 2013-04-16 09:08:29 +0000
+++ include/test/mir_test_doubles/stub_surface_target.h 2013-04-22 16:32:37 +0000
@@ -43,6 +43,10 @@
43 {43 {
44 return geometry::Size();44 return geometry::Size();
45 }45 }
46 geometry::Point top_left() const override
47 {
48 return geometry::Point();
49 }
46 std::string name() const override50 std::string name() const override
47 {51 {
48 return std::string();52 return std::string();
4953
=== modified file 'include/test/mir_test_framework/testing_server_configuration.h'
--- include/test/mir_test_framework/testing_server_configuration.h 2013-04-16 09:08:29 +0000
+++ include/test/mir_test_framework/testing_server_configuration.h 2013-04-22 16:32:37 +0000
@@ -49,7 +49,7 @@
49 // to avoid starting and stopping the full android input stack for tests49 // to avoid starting and stopping the full android input stack for tests
50 // which do not leverage input.50 // which do not leverage input.
51 std::shared_ptr<input::InputManager> the_input_manager();51 std::shared_ptr<input::InputManager> the_input_manager();
52 std::shared_ptr<shell::InputFocusSelector> the_input_focus_selector();52 std::shared_ptr<shell::InputTargetListener> the_input_target_listener();
5353
54 virtual std::string the_socket_file() const;54 virtual std::string the_socket_file() const;
55 using DefaultServerConfiguration::the_options;55 using DefaultServerConfiguration::the_options;
5656
=== modified file 'src/server/default_server_configuration.cpp'
--- src/server/default_server_configuration.cpp 2013-04-19 12:49:42 +0000
+++ src/server/default_server_configuration.cpp 2013-04-22 16:32:37 +0000
@@ -45,7 +45,7 @@
45#include "mir/graphics/buffer_initializer.h"45#include "mir/graphics/buffer_initializer.h"
46#include "mir/graphics/null_display_report.h"46#include "mir/graphics/null_display_report.h"
47#include "mir/input/null_input_manager.h"47#include "mir/input/null_input_manager.h"
48#include "mir/input/null_input_focus_selector.h"48#include "mir/input/null_input_target_listener.h"
49#include "input/android/default_android_input_configuration.h"49#include "input/android/default_android_input_configuration.h"
50#include "input/android/android_input_manager.h"50#include "input/android/android_input_manager.h"
51#include "input/android/android_dispatcher_controller.h"51#include "input/android/android_dispatcher_controller.h"
@@ -310,8 +310,7 @@
310 [this]310 [this]
311 {311 {
312 return std::make_shared<msh::SingleVisibilityFocusMechanism>(312 return std::make_shared<msh::SingleVisibilityFocusMechanism>(
313 the_shell_session_container(),313 the_shell_session_container());
314 the_input_focus_selector());
315 });314 });
316}315}
317316
@@ -347,7 +346,8 @@
347 the_shell_surface_factory(),346 the_shell_surface_factory(),
348 the_shell_session_container(),347 the_shell_session_container(),
349 the_shell_focus_sequence(),348 the_shell_focus_sequence(),
350 the_shell_focus_setter());349 the_shell_focus_setter(),
350 the_input_target_listener());
351 });351 });
352}352}
353353
@@ -562,15 +562,15 @@
562 return the_input_manager();562 return the_input_manager();
563}563}
564564
565std::shared_ptr<msh::InputFocusSelector> mir::DefaultServerConfiguration::the_input_focus_selector()565std::shared_ptr<msh::InputTargetListener> mir::DefaultServerConfiguration::the_input_target_listener()
566{566{
567 return input_focus_selector(567 return input_target_listener(
568 [&]() -> std::shared_ptr<msh::InputFocusSelector>568 [&]() -> std::shared_ptr<msh::InputTargetListener>
569 {569 {
570 if (the_options()->get("enable-input", false))570 if (the_options()->get("enable-input", false))
571 return std::make_shared<mia::DispatcherController>(the_input_configuration());571 return std::make_shared<mia::DispatcherController>(the_input_configuration());
572 else572 else
573 return std::make_shared<mi::NullInputFocusSelector>();573 return std::make_shared<mi::NullInputTargetListener>();
574 });574 });
575}575}
576576
577577
=== modified file 'src/server/display_server.cpp'
--- src/server/display_server.cpp 2013-04-19 14:52:23 +0000
+++ src/server/display_server.cpp 2013-04-22 16:32:37 +0000
@@ -31,9 +31,9 @@
3131
32namespace mc = mir::compositor;32namespace mc = mir::compositor;
33namespace mf = mir::frontend;33namespace mf = mir::frontend;
34namespace msh = mir::shell;
35namespace mg = mir::graphics;34namespace mg = mir::graphics;
36namespace mi = mir::input;35namespace mi = mir::input;
36namespace msh = mir::shell;
3737
38namespace38namespace
39{39{
4040
=== modified file 'src/server/input/android/android_dispatcher_controller.cpp'
--- src/server/input/android/android_dispatcher_controller.cpp 2013-04-11 23:06:12 +0000
+++ src/server/input/android/android_dispatcher_controller.cpp 2013-04-22 16:32:37 +0000
@@ -25,35 +25,85 @@
2525
26#include <InputDispatcher.h>26#include <InputDispatcher.h>
2727
28#include <boost/throw_exception.hpp>
29
30#include <stdexcept>
31#include <mutex>
32
28namespace mi = mir::input;33namespace mi = mir::input;
29namespace mia = mi::android;34namespace mia = mi::android;
3035
31mia::DispatcherController::DispatcherController(std::shared_ptr<mia::InputConfiguration> const& config) :36mia::DispatcherController::DispatcherController(std::shared_ptr<mia::InputConfiguration> const& config) :
32 input_dispatcher(config->the_dispatcher()),37 input_dispatcher(config->the_dispatcher())
33 focused_window_handle(0),38{
34 focused_application_handle(0)39}
35{40
36}41void mia::DispatcherController::input_application_opened(std::shared_ptr<mi::SessionTarget> const& session)
3742{
38void mia::DispatcherController::set_input_focus_to(std::shared_ptr<mi::SessionTarget> const& session,43 std::unique_lock<std::mutex> lock(handles_mutex);
39 std::shared_ptr<mi::SurfaceTarget> const& surface)44 if (application_handles.find(session) != application_handles.end())
40{45 BOOST_THROW_EXCEPTION(std::logic_error("An application was opened twice"));
41 if (focused_window_handle.get())46 application_handles[session] = new mia::InputApplicationHandle(session);
42 {47}
43 input_dispatcher->unregisterInputChannel(focused_window_handle->getInfo()->inputChannel);48
44 focused_window_handle.clear();49void mia::DispatcherController::input_application_closed(std::shared_ptr<mi::SessionTarget> const& session)
45 focused_application_handle.clear();50{
46 }51 std::unique_lock<std::mutex> lock(handles_mutex);
52 if (application_handles.find(session) == application_handles.end())
53 BOOST_THROW_EXCEPTION(std::logic_error("An application was closed twice"));
54 application_handles.erase(session);
55}
56
57void mia::DispatcherController::input_surface_opened(std::shared_ptr<mi::SessionTarget> const& session,
58 std::shared_ptr<input::SurfaceTarget> const& opened_surface)
59{
60 std::unique_lock<std::mutex> lock(handles_mutex);
61 auto application_handle = application_handles.find(session);
62 if (application_handle == application_handles.end())
63 BOOST_THROW_EXCEPTION(std::logic_error("A surface was opened for an unopened application"));
64 if (window_handles.find(opened_surface) != window_handles.end())
65 BOOST_THROW_EXCEPTION(std::logic_error("A surface was opened twice"));
66
67 droidinput::sp<droidinput::InputWindowHandle> window_handle = new mia::InputWindowHandle(application_handle->second, opened_surface);
68 input_dispatcher->registerInputChannel(window_handle->getInfo()->inputChannel, window_handle, false);
69
70 window_handles[opened_surface] = window_handle;
71}
72
73void mia::DispatcherController::input_surface_closed(std::shared_ptr<input::SurfaceTarget> const& closed_surface)
74{
75 std::unique_lock<std::mutex> lock(handles_mutex);
76 auto it = window_handles.find(closed_surface);
77 if (it == window_handles.end())
78 BOOST_THROW_EXCEPTION(std::logic_error("A surface was closed twice"));
79
80 input_dispatcher->unregisterInputChannel(it->second->getInfo()->inputChannel);
81 window_handles.erase(it);
82}
83
84void mia::DispatcherController::focus_cleared()
85{
86 droidinput::Vector<droidinput::sp<droidinput::InputWindowHandle>> empty_windows;
87 droidinput::sp<droidinput::InputApplicationHandle> null_application = nullptr;
88
89 input_dispatcher->setFocusedApplication(null_application);
90 input_dispatcher->setInputWindows(empty_windows);
91}
92
93void mia::DispatcherController::focus_changed(std::shared_ptr<mi::SurfaceTarget> const& surface)
94{
95 std::unique_lock<std::mutex> lock(handles_mutex);
96
97 auto window_handle = window_handles[surface];
98
99 if (!window_handle.get())
100 BOOST_THROW_EXCEPTION(std::logic_error("Focus changed to an unopened surface"));
101 auto application_handle = window_handle->inputApplicationHandle;
102
103 input_dispatcher->setFocusedApplication(application_handle);
47104
48 droidinput::Vector<droidinput::sp<droidinput::InputWindowHandle>> windows;105 droidinput::Vector<droidinput::sp<droidinput::InputWindowHandle>> windows;
49 if (surface)106 windows.push_back(window_handle);
50 {
51 focused_application_handle = new mia::InputApplicationHandle(session);
52 focused_window_handle = new mia::InputWindowHandle(focused_application_handle, surface);
53 input_dispatcher->setFocusedApplication(focused_application_handle);
54107
55 input_dispatcher->registerInputChannel(focused_window_handle->getInfo()->inputChannel, focused_window_handle, false);
56 windows.push_back(focused_window_handle);
57 }
58 input_dispatcher->setInputWindows(windows);108 input_dispatcher->setInputWindows(windows);
59}109}
60110
=== modified file 'src/server/input/android/android_dispatcher_controller.h'
--- src/server/input/android/android_dispatcher_controller.h 2013-04-11 23:06:12 +0000
+++ src/server/input/android/android_dispatcher_controller.h 2013-04-22 16:32:37 +0000
@@ -19,10 +19,13 @@
19#ifndef MIR_INPUT_ANDROID_DISPATCHER_CONTROLLER_H_19#ifndef MIR_INPUT_ANDROID_DISPATCHER_CONTROLLER_H_
20#define MIR_INPUT_ANDROID_DISPATCHER_CONTROLLER_H_20#define MIR_INPUT_ANDROID_DISPATCHER_CONTROLLER_H_
2121
22#include "mir/shell/input_focus_selector.h"22#include "mir/shell/input_target_listener.h"
2323
24#include <utils/StrongPointer.h>24#include <utils/StrongPointer.h>
2525
26#include <map>
27#include <mutex>
28
26namespace android29namespace android
27{30{
28class InputDispatcherInterface;31class InputDispatcherInterface;
@@ -40,13 +43,21 @@
40{43{
41class InputConfiguration;44class InputConfiguration;
4245
43class DispatcherController : public shell::InputFocusSelector46class DispatcherController : public shell::InputTargetListener
44{47{
45public:48public:
46 explicit DispatcherController(std::shared_ptr<InputConfiguration> const& input_configuration);49 explicit DispatcherController(std::shared_ptr<InputConfiguration> const& input_configuration);
47 virtual ~DispatcherController() = default;50 virtual ~DispatcherController() noexcept(true) {}
48 51
49 void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& session, std::shared_ptr<input::SurfaceTarget> const& surface);52 void input_application_opened(std::shared_ptr<input::SessionTarget> const& application);
53 void input_application_closed(std::shared_ptr<input::SessionTarget> const& application);
54
55 void input_surface_opened(std::shared_ptr<input::SessionTarget> const& application,
56 std::shared_ptr<input::SurfaceTarget> const& opened_surface);
57 void input_surface_closed(std::shared_ptr<input::SurfaceTarget> const& closed_surface);
58
59 void focus_changed(std::shared_ptr<input::SurfaceTarget> const& focus_surface);
60 void focus_cleared();
5061
51protected:62protected:
52 DispatcherController(const DispatcherController&) = delete;63 DispatcherController(const DispatcherController&) = delete;
@@ -55,8 +66,10 @@
55private:66private:
56 droidinput::sp<droidinput::InputDispatcherInterface> input_dispatcher;67 droidinput::sp<droidinput::InputDispatcherInterface> input_dispatcher;
5768
58 droidinput::sp<droidinput::InputWindowHandle> focused_window_handle;69 std::map<std::shared_ptr<input::SessionTarget>, droidinput::sp<droidinput::InputApplicationHandle>> application_handles;
59 droidinput::sp<droidinput::InputApplicationHandle> focused_application_handle;70 std::map<std::shared_ptr<input::SurfaceTarget>, droidinput::sp<droidinput::InputWindowHandle>> window_handles;
71
72 std::mutex handles_mutex;
60};73};
6174
62}75}
6376
=== modified file 'src/server/input/android/android_input_window_handle.cpp'
--- src/server/input/android/android_input_window_handle.cpp 2013-03-29 16:51:35 +0000
+++ src/server/input/android/android_input_window_handle.cpp 2013-04-22 16:32:37 +0000
@@ -48,11 +48,17 @@
48 surface->server_input_fd());48 surface->server_input_fd());
49 }49 }
5050
51 mInfo->frameLeft = 0;51 auto surface_position = surface->top_left();
52 mInfo->frameTop = 0;52 mInfo->frameLeft = surface_position.x.as_uint32_t();
53 mInfo->frameTop = surface_position.y.as_uint32_t();
53 auto surface_size = surface->size();54 auto surface_size = surface->size();
54 mInfo->frameRight = mInfo->frameLeft + surface_size.width.as_uint32_t();55 mInfo->frameRight = mInfo->frameLeft + surface_size.width.as_uint32_t();
55 mInfo->frameBottom = mInfo->frameTop + surface_size.height.as_uint32_t();56 mInfo->frameBottom = mInfo->frameTop + surface_size.height.as_uint32_t();
57
58 mInfo->touchableRegionLeft = mInfo->frameLeft;
59 mInfo->touchableRegionTop = mInfo->frameTop;
60 mInfo->touchableRegionRight = mInfo->frameRight;
61 mInfo->touchableRegionBottom = mInfo->frameBottom;
5662
57 mInfo->name = droidinput::String8(surface->name().c_str());63 mInfo->name = droidinput::String8(surface->name().c_str());
58 mInfo->layoutParamsFlags = droidinput::InputWindowInfo::FLAG_NOT_TOUCH_MODAL;64 mInfo->layoutParamsFlags = droidinput::InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
5965
=== modified file 'src/server/input/android/default_android_input_configuration.cpp'
--- src/server/input/android/default_android_input_configuration.cpp 2013-04-16 09:08:29 +0000
+++ src/server/input/android/default_android_input_configuration.cpp 2013-04-22 16:32:37 +0000
@@ -98,7 +98,7 @@
98 return dispatcher_policy(98 return dispatcher_policy(
99 [this]()99 [this]()
100 {100 {
101 return new mia::EventFilterDispatcherPolicy(filter_chain);101 return new mia::EventFilterDispatcherPolicy(filter_chain, is_key_repeat_enabled());
102 });102 });
103}103}
104104
@@ -149,3 +149,8 @@
149 new droidinput::InputReaderThread(the_reader()));149 new droidinput::InputReaderThread(the_reader()));
150 });150 });
151}151}
152
153bool mia::DefaultInputConfiguration::is_key_repeat_enabled()
154{
155 return true;
156}
152157
=== modified file 'src/server/input/android/default_android_input_configuration.h'
--- src/server/input/android/default_android_input_configuration.h 2013-04-16 09:08:29 +0000
+++ src/server/input/android/default_android_input_configuration.h 2013-04-22 16:32:37 +0000
@@ -69,6 +69,8 @@
6969
70 virtual droidinput::sp<droidinput::InputDispatcherPolicyInterface> the_dispatcher_policy();70 virtual droidinput::sp<droidinput::InputDispatcherPolicyInterface> the_dispatcher_policy();
71 virtual droidinput::sp<droidinput::InputReaderPolicyInterface> the_reader_policy();71 virtual droidinput::sp<droidinput::InputReaderPolicyInterface> the_reader_policy();
72
73 virtual bool is_key_repeat_enabled();
7274
73protected:75protected:
74 DefaultInputConfiguration(DefaultInputConfiguration const&) = delete;76 DefaultInputConfiguration(DefaultInputConfiguration const&) = delete;
7577
=== modified file 'src/server/input/android/event_filter_dispatcher_policy.cpp'
--- src/server/input/android/event_filter_dispatcher_policy.cpp 2013-04-16 09:27:00 +0000
+++ src/server/input/android/event_filter_dispatcher_policy.cpp 2013-04-22 16:32:37 +0000
@@ -21,8 +21,9 @@
21namespace mi = mir::input;21namespace mi = mir::input;
22namespace mia = mi::android;22namespace mia = mi::android;
2323
24mia::EventFilterDispatcherPolicy::EventFilterDispatcherPolicy(std::shared_ptr<mi::EventFilter> const& event_filter) :24mia::EventFilterDispatcherPolicy::EventFilterDispatcherPolicy(std::shared_ptr<mi::EventFilter> const& event_filter, bool key_repeat_enabled) :
25 event_filter(event_filter)25 event_filter(event_filter),
26 key_repeat_enabled(key_repeat_enabled)
26{27{
27}28}
2829
@@ -46,7 +47,7 @@
4647
47bool mia::EventFilterDispatcherPolicy::isKeyRepeatEnabled()48bool mia::EventFilterDispatcherPolicy::isKeyRepeatEnabled()
48{49{
49 return true;50 return key_repeat_enabled;
50}51}
5152
52bool mia::EventFilterDispatcherPolicy::filterInputEvent(const droidinput::InputEvent* input_event, uint32_t /*policy_flags*/)53bool mia::EventFilterDispatcherPolicy::filterInputEvent(const droidinput::InputEvent* input_event, uint32_t /*policy_flags*/)
@@ -67,9 +68,9 @@
67 policy_flags |= droidinput::POLICY_FLAG_PASS_TO_USER;68 policy_flags |= droidinput::POLICY_FLAG_PASS_TO_USER;
68}69}
6970
70void mia::EventFilterDispatcherPolicy::interceptMotionBeforeQueueing(nsecs_t /* when */, uint32_t& /* policyFlags */)71void mia::EventFilterDispatcherPolicy::interceptMotionBeforeQueueing(nsecs_t /* when */, uint32_t& policy_flags)
71{72{
72 // TODO: Implement for motion events to client.73 policy_flags |= droidinput::POLICY_FLAG_PASS_TO_USER;
73}74}
7475
75nsecs_t mia::EventFilterDispatcherPolicy::interceptKeyBeforeDispatching(76nsecs_t mia::EventFilterDispatcherPolicy::interceptKeyBeforeDispatching(
7677
=== modified file 'src/server/input/android/event_filter_dispatcher_policy.h'
--- src/server/input/android/event_filter_dispatcher_policy.h 2013-04-16 09:08:29 +0000
+++ src/server/input/android/event_filter_dispatcher_policy.h 2013-04-22 16:32:37 +0000
@@ -40,7 +40,7 @@
40class EventFilterDispatcherPolicy : public droidinput::InputDispatcherPolicyInterface40class EventFilterDispatcherPolicy : public droidinput::InputDispatcherPolicyInterface
41{41{
42public:42public:
43 EventFilterDispatcherPolicy(std::shared_ptr<EventFilter> const& event_filter);43 EventFilterDispatcherPolicy(std::shared_ptr<EventFilter> const& event_filter, bool key_repeat_enabled);
44 virtual ~EventFilterDispatcherPolicy() {}44 virtual ~EventFilterDispatcherPolicy() {}
4545
46 void notifyConfigurationChanged(nsecs_t when);46 void notifyConfigurationChanged(nsecs_t when);
@@ -71,6 +71,7 @@
71 EventFilterDispatcherPolicy& operator=(const EventFilterDispatcherPolicy&) = delete;71 EventFilterDispatcherPolicy& operator=(const EventFilterDispatcherPolicy&) = delete;
72private:72private:
73 std::shared_ptr<EventFilter> event_filter;73 std::shared_ptr<EventFilter> event_filter;
74 bool key_repeat_enabled;
74};75};
7576
76}77}
7778
=== modified file 'src/server/shell/application_session.cpp'
--- src/server/shell/application_session.cpp 2013-04-16 17:42:26 +0000
+++ src/server/shell/application_session.cpp 2013-04-22 16:32:37 +0000
@@ -18,8 +18,8 @@
1818
19#include "mir/shell/application_session.h"19#include "mir/shell/application_session.h"
20#include "mir/shell/surface.h"20#include "mir/shell/surface.h"
21
22#include "mir/shell/surface_factory.h"21#include "mir/shell/surface_factory.h"
22#include "mir/shell/input_target_listener.h"
2323
24#include <boost/throw_exception.hpp>24#include <boost/throw_exception.hpp>
2525
@@ -32,9 +32,11 @@
32namespace msh = mir::shell;32namespace msh = mir::shell;
3333
34msh::ApplicationSession::ApplicationSession(34msh::ApplicationSession::ApplicationSession(
35 std::shared_ptr<SurfaceFactory> const& surface_factory,35 std::shared_ptr<msh::SurfaceFactory> const& surface_factory,
36 std::shared_ptr<msh::InputTargetListener> const& input_target_listener,
36 std::string const& session_name) :37 std::string const& session_name) :
37 surface_factory(surface_factory),38 surface_factory(surface_factory),
39 input_target_listener(input_target_listener),
38 session_name(session_name),40 session_name(session_name),
39 next_surface_id(0)41 next_surface_id(0)
40{42{
@@ -46,6 +48,7 @@
46 std::unique_lock<std::mutex> lock(surfaces_mutex);48 std::unique_lock<std::mutex> lock(surfaces_mutex);
47 for (auto const& pair_id_surface : surfaces)49 for (auto const& pair_id_surface : surfaces)
48 {50 {
51 input_target_listener->input_surface_closed(pair_id_surface.second);
49 pair_id_surface.second->destroy();52 pair_id_surface.second->destroy();
50 }53 }
51}54}
@@ -95,6 +98,7 @@
95 std::unique_lock<std::mutex> lock(surfaces_mutex);98 std::unique_lock<std::mutex> lock(surfaces_mutex);
96 auto p = checked_find(id);99 auto p = checked_find(id);
97100
101 input_target_listener->input_surface_closed(p->second);
98 p->second->destroy();102 p->second->destroy();
99 surfaces.erase(p);103 surfaces.erase(p);
100}104}
101105
=== modified file 'src/server/shell/session_manager.cpp'
--- src/server/shell/session_manager.cpp 2013-04-19 09:15:31 +0000
+++ src/server/shell/session_manager.cpp 2013-04-22 16:32:37 +0000
@@ -23,6 +23,8 @@
23#include "mir/shell/focus_sequence.h"23#include "mir/shell/focus_sequence.h"
24#include "mir/shell/focus_setter.h"24#include "mir/shell/focus_setter.h"
25#include "mir/shell/session.h"25#include "mir/shell/session.h"
26#include "mir/shell/surface.h"
27#include "mir/shell/input_target_listener.h"
2628
27#include <memory>29#include <memory>
28#include <cassert>30#include <cassert>
@@ -31,20 +33,22 @@
31namespace mf = mir::frontend;33namespace mf = mir::frontend;
32namespace msh = mir::shell;34namespace msh = mir::shell;
3335
34msh::SessionManager::SessionManager(36msh::SessionManager::SessionManager(std::shared_ptr<msh::SurfaceFactory> const& surface_factory,
35 std::shared_ptr<msh::SurfaceFactory> const& surface_factory,
36 std::shared_ptr<msh::SessionContainer> const& container,37 std::shared_ptr<msh::SessionContainer> const& container,
37 std::shared_ptr<msh::FocusSequence> const& sequence,38 std::shared_ptr<msh::FocusSequence> const& sequence,
38 std::shared_ptr<msh::FocusSetter> const& focus_setter) :39 std::shared_ptr<msh::FocusSetter> const& focus_setter,
40 std::shared_ptr<msh::InputTargetListener> const& input_target_listener) :
39 surface_factory(surface_factory),41 surface_factory(surface_factory),
40 app_container(container),42 app_container(container),
41 focus_sequence(sequence),43 focus_sequence(sequence),
42 focus_setter(focus_setter)44 focus_setter(focus_setter),
45 input_target_listener(input_target_listener)
43{46{
44 assert(surface_factory);47 assert(surface_factory);
45 assert(sequence);48 assert(sequence);
46 assert(container);49 assert(container);
47 assert(focus_setter);50 assert(focus_setter);
51 assert(input_target_listener);
48}52}
4953
50msh::SessionManager::~SessionManager()54msh::SessionManager::~SessionManager()
@@ -53,25 +57,36 @@
5357
54std::shared_ptr<mf::Session> msh::SessionManager::open_session(std::string const& name)58std::shared_ptr<mf::Session> msh::SessionManager::open_session(std::string const& name)
55{59{
56 auto new_session = std::make_shared<msh::ApplicationSession>(surface_factory, name);60 auto new_session = std::make_shared<msh::ApplicationSession>(surface_factory, input_target_listener, name);
5761
58 app_container->insert_session(new_session);62 app_container->insert_session(new_session);
63
64 input_target_listener->input_application_opened(new_session);
5965
60 set_focus_to_locked(std::unique_lock<std::mutex>(mutex), new_session);66 set_focus_to_locked(std::unique_lock<std::mutex>(mutex), new_session);
6167
62 return new_session;68 return new_session;
63}69}
6470
65inline void msh::SessionManager::set_focus_to_locked(std::unique_lock<std::mutex> const&, std::shared_ptr<Session> const& next_focus)71inline void msh::SessionManager::set_focus_to_locked(std::unique_lock<std::mutex> const&, std::shared_ptr<Session> const& shell_session)
66{72{
67 focus_application = next_focus;73 auto old_focus = focus_application.lock();
68 focus_setter->set_focus_to(next_focus);74
75 focus_application = shell_session;
76 focus_setter->set_focus_to(shell_session);
77
78 if (shell_session && shell_session->default_surface())
79 input_target_listener->focus_changed(shell_session->default_surface());
80 else if (shell_session == old_focus || !shell_session)
81 input_target_listener->focus_cleared();
69}82}
7083
71void msh::SessionManager::close_session(std::shared_ptr<mf::Session> const& session)84void msh::SessionManager::close_session(std::shared_ptr<mf::Session> const& session)
72{85{
73 auto shell_session = std::dynamic_pointer_cast<Session>(session);86 auto shell_session = std::dynamic_pointer_cast<Session>(session);
7487
88 input_target_listener->input_application_closed(shell_session);
89
75 app_container->remove_session(shell_session);90 app_container->remove_session(shell_session);
7691
77 std::unique_lock<std::mutex> lock(mutex);92 std::unique_lock<std::mutex> lock(mutex);
@@ -133,9 +148,11 @@
133 mf::SurfaceCreationParameters const& params)148 mf::SurfaceCreationParameters const& params)
134{149{
135 auto shell_session = std::dynamic_pointer_cast<Session>(session);150 auto shell_session = std::dynamic_pointer_cast<Session>(session);
136 auto id = session->create_surface(params);151 auto id = shell_session->create_surface(params);
152
153 input_target_listener->input_surface_opened(shell_session,
154 std::dynamic_pointer_cast<msh::Surface>(shell_session->get_surface(id)));
137 set_focus_to_locked(std::unique_lock<std::mutex>(mutex), shell_session);155 set_focus_to_locked(std::unique_lock<std::mutex>(mutex), shell_session);
138156
139 return id;157 return id;
140}158}
141
142159
=== modified file 'src/server/shell/single_visibility_focus_mechanism.cpp'
--- src/server/shell/single_visibility_focus_mechanism.cpp 2013-04-18 22:57:01 +0000
+++ src/server/shell/single_visibility_focus_mechanism.cpp 2013-04-22 16:32:37 +0000
@@ -19,7 +19,6 @@
19#include "mir/shell/session_container.h"19#include "mir/shell/session_container.h"
20#include "mir/frontend/session.h"20#include "mir/frontend/session.h"
21#include "mir/shell/single_visibility_focus_mechanism.h"21#include "mir/shell/single_visibility_focus_mechanism.h"
22#include "mir/shell/input_focus_selector.h"
2322
24#include "mir/shell/session.h"23#include "mir/shell/session.h"
25#include "mir/shell/surface.h"24#include "mir/shell/surface.h"
@@ -27,10 +26,8 @@
27namespace mf = mir::frontend;26namespace mf = mir::frontend;
28namespace msh = mir::shell;27namespace msh = mir::shell;
2928
30msh::SingleVisibilityFocusMechanism::SingleVisibilityFocusMechanism(std::shared_ptr<msh::SessionContainer> const& app_container,29msh::SingleVisibilityFocusMechanism::SingleVisibilityFocusMechanism(std::shared_ptr<msh::SessionContainer> const& app_container)
31 std::shared_ptr<msh::InputFocusSelector> const& input_selector)30 : app_container(app_container)
32 : app_container(app_container),
33 input_selector(input_selector)
34{31{
35}32}
3633
@@ -41,8 +38,6 @@
41 if (session == focus_session)38 if (session == focus_session)
42 {39 {
43 session->show();40 session->show();
44
45 input_selector->set_input_focus_to(focus_session, focus_session->default_surface());
46 }41 }
47 else42 else
48 {43 {
4944
=== modified file 'src/server/shell/surface.cpp'
--- src/server/shell/surface.cpp 2013-04-16 17:42:26 +0000
+++ src/server/shell/surface.cpp 2013-04-22 16:32:37 +0000
@@ -88,6 +88,18 @@
88 }88 }
89}89}
9090
91mir::geometry::Point msh::Surface::top_left() const
92{
93 if (auto const& s = surface.lock())
94 {
95 return s->top_left();
96 }
97 else
98 {
99 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid surface"));
100 }
101}
102
91std::string msh::Surface::name() const103std::string msh::Surface::name() const
92{104{
93 if (auto const& s = surface.lock())105 if (auto const& s = surface.lock())
94106
=== modified file 'tests/acceptance-tests/test_client_input.cpp'
--- tests/acceptance-tests/test_client_input.cpp 2013-04-17 07:31:40 +0000
+++ tests/acceptance-tests/test_client_input.cpp 2013-04-22 16:32:37 +0000
@@ -65,10 +65,9 @@
6565
66 }66 }
67 67
68 void set_input_focus_to(68 void focus_changed(std::shared_ptr<mi::SurfaceTarget> const& surface) override
69 std::shared_ptr<mi::SessionTarget> const& session, std::shared_ptr<mi::SurfaceTarget> const& surface) override
70 {69 {
71 DispatcherController::set_input_focus_to(session, surface);70 DispatcherController::focus_changed(surface);
72 71
73 // We need a synchronization primitive inorder to halt test event injection72 // We need a synchronization primitive inorder to halt test event injection
74 // until after a surface has taken focus (lest the events be discarded).73 // until after a surface has taken focus (lest the events be discarded).
@@ -96,6 +95,7 @@
96 {95 {
97 on_focus_set.wait_for_at_most_seconds(10);96 on_focus_set.wait_for_at_most_seconds(10);
98 fake_event_hub->synthesize_builtin_keyboard_added();97 fake_event_hub->synthesize_builtin_keyboard_added();
98 fake_event_hub->synthesize_builtin_cursor_added();
99 fake_event_hub->synthesize_device_scan_complete();99 fake_event_hub->synthesize_device_scan_complete();
100 inject_input();100 inject_input();
101 });101 });
@@ -122,10 +122,10 @@
122 });122 });
123 }123 }
124124
125 std::shared_ptr<msh::InputFocusSelector>125 std::shared_ptr<msh::InputTargetListener>
126 the_input_focus_selector() override126 the_input_target_listener() override
127 {127 {
128 return input_focus_selector(128 return input_target_listener(
129 [this]()129 [this]()
130 {130 {
131 return std::make_shared<FocusNotifyingDispatcherController>(mt::fake_shared(input_config), on_focus_set);131 return std::make_shared<FocusNotifyingDispatcherController>(mt::fake_shared(input_config), on_focus_set);
@@ -186,7 +186,7 @@
186186
187struct MockInputHandler187struct MockInputHandler
188{188{
189 MOCK_METHOD1(handle_key_down, void(MirEvent const*));189 MOCK_METHOD1(handle_input, bool(MirEvent const*));
190};190};
191191
192struct InputReceivingClient : ClientConfigCommon192struct InputReceivingClient : ClientConfigCommon
@@ -201,9 +201,9 @@
201 static void handle_input(MirSurface* /* surface */, MirEvent const* ev, void* context)201 static void handle_input(MirSurface* /* surface */, MirEvent const* ev, void* context)
202 {202 {
203 auto client = static_cast<InputReceivingClient *>(context);203 auto client = static_cast<InputReceivingClient *>(context);
204 if (ev->key.action == 0)204
205 if(client->handler->handle_input(ev))
205 {206 {
206 client->handler->handle_key_down(ev);
207 client->event_received[client->events_received].wake_up_everyone();207 client->event_received[client->events_received].wake_up_everyone();
208 client->events_received++;208 client->events_received++;
209 }209 }
@@ -227,7 +227,7 @@
227 MirSurfaceParameters const request_params =227 MirSurfaceParameters const request_params =
228 {228 {
229 __PRETTY_FUNCTION__,229 __PRETTY_FUNCTION__,
230 640, 480,230 surface_width, surface_height,
231 mir_pixel_format_abgr_8888,231 mir_pixel_format_abgr_8888,
232 mir_buffer_usage_hardware232 mir_buffer_usage_hardware
233 };233 };
@@ -259,9 +259,66 @@
259 259
260 int events_to_receive;260 int events_to_receive;
261 int events_received;261 int events_received;
262
263 static int const surface_width = 100;
264 static int const surface_height = 100;
262};265};
263266
264}267MATCHER(KeyDownEvent, "")
268{
269 if (arg->type != mir_event_type_key)
270 return false;
271 if (arg->key.action != 0) // Key down
272 return false;
273
274 return true;
275}
276MATCHER_P(KeyOfSymbol, keysym, "")
277{
278 if (static_cast<xkb_keysym_t>(arg->key.key_code) == (uint)keysym)
279 return true;
280 return false;
281}
282
283MATCHER(HoverEnterEvent, "")
284{
285 if (arg->type != mir_event_type_motion)
286 return false;
287 if (arg->motion.action != AMOTION_EVENT_ACTION_HOVER_ENTER)
288 return false;
289
290 return true;
291}
292
293MATCHER_P2(ButtonDownEvent, x, y, "")
294{
295 if (arg->type != mir_event_type_motion)
296 return false;
297 if (arg->motion.action != AMOTION_EVENT_ACTION_DOWN)
298 return false;
299 printf("action: %d \n", arg->motion.action);
300 if (arg->motion.button_state == 0)
301 return false;
302 if (arg->motion.pointer_coordinates[0].x != x)
303 return false;
304 if (arg->motion.pointer_coordinates[0].y != y)
305 return false;
306 return true;
307}
308
309MATCHER_P2(MotionEventWithPosition, x, y, "")
310{
311 if (arg->type != mir_event_type_motion)
312 return false;
313 if (arg->motion.pointer_coordinates[0].x != x)
314 return false;
315 if (arg->motion.pointer_coordinates[0].y != y)
316 return false;
317 return true;
318}
319
320}
321
265322
266using TestClientInput = BespokeDisplayServerTestFixture;323using TestClientInput = BespokeDisplayServerTestFixture;
267324
@@ -290,22 +347,13 @@
290 void expect_input()347 void expect_input()
291 {348 {
292 using namespace ::testing;349 using namespace ::testing;
293 EXPECT_CALL(*handler, handle_key_down(_)).Times(num_events_produced);350 EXPECT_CALL(*handler, handle_input(KeyDownEvent())).Times(num_events_produced)
351 .WillRepeatedly(Return(true));
294 }352 }
295 } client_config;353 } client_config;
296 launch_client_process(client_config);354 launch_client_process(client_config);
297}355}
298356
299namespace
300{
301MATCHER_P(KeyOfSymbol, keysym, "")
302{
303 if (static_cast<xkb_keysym_t>(arg->key.key_code) == (uint)keysym)
304 return true;
305 return false;
306}
307}
308
309TEST_F(TestClientInput, clients_receive_us_english_mapped_keys)357TEST_F(TestClientInput, clients_receive_us_english_mapped_keys)
310{358{
311 using namespace ::testing;359 using namespace ::testing;
@@ -319,12 +367,6 @@
319 fake_event_hub->synthesize_event(mis::a_key_down_event()367 fake_event_hub->synthesize_event(mis::a_key_down_event()
320 .of_scancode(KEY_4));368 .of_scancode(KEY_4));
321369
322 // Release the keys so we don't get repeat events.
323 fake_event_hub->synthesize_event(mis::a_key_up_event()
324 .of_scancode(KEY_4));
325 fake_event_hub->synthesize_event(mis::a_key_up_event()
326 .of_scancode(KEY_LEFTSHIFT));
327
328 }370 }
329 } server_config;371 } server_config;
330 launch_server_process(server_config);372 launch_server_process(server_config);
@@ -338,10 +380,78 @@
338 using namespace ::testing;380 using namespace ::testing;
339381
340 InSequence seq;382 InSequence seq;
341 EXPECT_CALL(*handler, handle_key_down(KeyOfSymbol(XKB_KEY_Shift_L))).Times(1);383 EXPECT_CALL(*handler, handle_input(AllOf(KeyDownEvent(), KeyOfSymbol(XKB_KEY_Shift_L)))).Times(1)
342 EXPECT_CALL(*handler, handle_key_down(KeyOfSymbol(XKB_KEY_dollar))).Times(1);384 .WillOnce(Return(true));
343 }385 EXPECT_CALL(*handler, handle_input(AllOf(KeyDownEvent(), KeyOfSymbol(XKB_KEY_dollar)))).Times(1)
344 } client_config;386 .WillOnce(Return(true));
345 launch_client_process(client_config);387 }
346}388 } client_config;
347389 launch_client_process(client_config);
390}
391
392// TODO: This assumes that clients are placed by shell at 0,0. Which probably isn't quite safe!
393TEST_F(TestClientInput, clients_receive_motion_inside_window)
394{
395 using namespace ::testing;
396
397 struct InputProducingServerConfiguration : FakeInputServerConfiguration
398 {
399 void inject_input()
400 {
401 fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(InputReceivingClient::surface_width,
402 InputReceivingClient::surface_height));
403 fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(2,2));
404 }
405 } server_config;
406 launch_server_process(server_config);
407
408 struct MotionReceivingClient : InputReceivingClient
409 {
410 MotionReceivingClient() : InputReceivingClient(2) {}
411
412 void expect_input()
413 {
414 using namespace ::testing;
415
416 InSequence seq;
417
418 // We should see the cursor enter
419 EXPECT_CALL(*handler, handle_input(HoverEnterEvent())).Times(1).WillOnce(Return(true));
420 EXPECT_CALL(*handler, handle_input(
421 MotionEventWithPosition(InputReceivingClient::surface_width,
422 InputReceivingClient::surface_height))).Times(1).WillOnce(Return(true));
423 // But we should not receive an event for the second movement outside of our surface!
424 }
425 } client_config;
426 launch_client_process(client_config);
427}
428
429TEST_F(TestClientInput, clients_receive_button_events_inside_window)
430{
431 using namespace ::testing;
432
433 struct InputProducingServerConfiguration : FakeInputServerConfiguration
434 {
435 void inject_input()
436 {
437 fake_event_hub->synthesize_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down));
438 }
439 } server_config;
440 launch_server_process(server_config);
441
442 struct ButtonReceivingClient : InputReceivingClient
443 {
444 ButtonReceivingClient() : InputReceivingClient(1) {}
445
446 void expect_input()
447 {
448 using namespace ::testing;
449
450 InSequence seq;
451
452 // The cursor starts at (0, 0).
453 EXPECT_CALL(*handler, handle_input(ButtonDownEvent(0, 0))).Times(1).WillOnce(Return(true));
454 }
455 } client_config;
456 launch_client_process(client_config);
457}
348458
=== modified file 'tests/acceptance-tests/test_focus_selection.cpp'
--- tests/acceptance-tests/test_focus_selection.cpp 2013-04-18 02:52:30 +0000
+++ tests/acceptance-tests/test_focus_selection.cpp 2013-04-22 16:32:37 +0000
@@ -24,11 +24,11 @@
24#include "mir/shell/organising_surface_factory.h"24#include "mir/shell/organising_surface_factory.h"
25#include "mir/shell/session_manager.h"25#include "mir/shell/session_manager.h"
26#include "mir/graphics/display.h"26#include "mir/graphics/display.h"
27#include "mir/shell/input_focus_selector.h"27#include "mir/shell/input_target_listener.h"
2828
29#include "mir_test_framework/display_server_test_fixture.h"29#include "mir_test_framework/display_server_test_fixture.h"
30#include "mir_test_doubles/mock_focus_setter.h"30#include "mir_test_doubles/mock_focus_setter.h"
31#include "mir_test_doubles/mock_input_focus_selector.h"31#include "mir_test_doubles/mock_input_target_listener.h"
3232
33#include <gtest/gtest.h>33#include <gtest/gtest.h>
34#include <gmock/gmock.h>34#include <gmock/gmock.h>
@@ -36,7 +36,8 @@
36namespace mf = mir::frontend;36namespace mf = mir::frontend;
37namespace msh = mir::shell;37namespace msh = mir::shell;
38namespace mi = mir::input;38namespace mi = mir::input;
39namespace mtd = mir::test::doubles;39namespace mt = mir::test;
40namespace mtd = mt::doubles;
40namespace mtf = mir_test_framework;41namespace mtf = mir_test_framework;
4142
42namespace43namespace
@@ -46,6 +47,7 @@
4647
47namespace48namespace
48{49{
50
49struct ClientConfigCommon : TestingClientConfiguration51struct ClientConfigCommon : TestingClientConfiguration
50{52{
51 ClientConfigCommon() :53 ClientConfigCommon() :
@@ -121,18 +123,10 @@
121{123{
122 return arg != std::shared_ptr<msh::Session>();124 return arg != std::shared_ptr<msh::Session>();
123}125}
124MATCHER(NonNullSessionTarget, "")
125{
126 return arg != std::shared_ptr<mi::SessionTarget>();
127}
128MATCHER(NonNullSurfaceTarget, "")126MATCHER(NonNullSurfaceTarget, "")
129{127{
130 return arg != std::shared_ptr<mi::SurfaceTarget>();128 return arg != std::shared_ptr<mi::SurfaceTarget>();
131}129}
132MATCHER(NullSurfaceTarget, "")
133{
134 return arg == std::shared_ptr<mi::SurfaceTarget>();
135}
136}130}
137131
138TEST_F(BespokeDisplayServerTestFixture, sessions_creating_surface_receive_focus)132TEST_F(BespokeDisplayServerTestFixture, sessions_creating_surface_receive_focus)
@@ -148,7 +142,6 @@
148 using namespace ::testing;142 using namespace ::testing;
149143
150 auto focus_setter = std::make_shared<mtd::MockFocusSetter>();144 auto focus_setter = std::make_shared<mtd::MockFocusSetter>();
151
152 {145 {
153 InSequence seq;146 InSequence seq;
154 // Once on application registration and once on surface creation147 // Once on application registration and once on surface creation
@@ -174,30 +167,37 @@
174{167{
175 struct ServerConfig : TestingServerConfiguration168 struct ServerConfig : TestingServerConfiguration
176 {169 {
177 std::shared_ptr<mtd::MockInputFocusSelector> focus_selector;170 std::shared_ptr<mtd::MockInputTargetListener> target_listener;
178 bool expected;171 bool expected;
179172
180 ServerConfig()173 ServerConfig()
181 : focus_selector(std::make_shared<mtd::MockInputFocusSelector>()),174 : target_listener(std::make_shared<mtd::MockInputTargetListener>()),
182 expected(false)175 expected(false)
183 {176 {
184 }177 }
185178
186 std::shared_ptr<msh::InputFocusSelector>179 std::shared_ptr<msh::InputTargetListener>
187 the_input_focus_selector() override180 the_input_target_listener() override
188 {181 {
189 using namespace ::testing;182 using namespace ::testing;
190183
191 if (!expected)184 if (!expected)
192 {185 {
193 InSequence seq;186
187 EXPECT_CALL(*target_listener, input_application_opened(_)).Times(AtLeast(0));
188 EXPECT_CALL(*target_listener, input_application_closed(_)).Times(AtLeast(0));
189 EXPECT_CALL(*target_listener, input_surface_opened(_,_)).Times(AtLeast(0));
190 EXPECT_CALL(*target_listener, input_surface_closed(_)).Times(AtLeast(0));
191 EXPECT_CALL(*target_listener, focus_cleared()).Times(AtLeast(0));
194192
195 EXPECT_CALL(*focus_selector, set_input_focus_to(NonNullSessionTarget(), NullSurfaceTarget())).Times(1);193 {
196 EXPECT_CALL(*focus_selector, set_input_focus_to(NonNullSessionTarget(), NonNullSurfaceTarget())).Times(1);194 InSequence seq;
197 expected = true;195 EXPECT_CALL(*target_listener, focus_changed(NonNullSurfaceTarget())).Times(1);
196 expected = true;
197 }
198 }198 }
199199
200 return focus_selector;200 return target_listener;
201 }201 }
202 } server_config;202 } server_config;
203203
204204
=== modified file 'tests/death-tests/test_application_manager_death.cpp'
--- tests/death-tests/test_application_manager_death.cpp 2013-03-21 03:32:59 +0000
+++ tests/death-tests/test_application_manager_death.cpp 2013-04-22 16:32:37 +0000
@@ -30,11 +30,12 @@
30// ::testing::FLAGS_gtest_death_test_style = "threadsafe";30// ::testing::FLAGS_gtest_death_test_style = "threadsafe";
31// leads to the test failing under valgrind31// leads to the test failing under valgrind
32 EXPECT_EXIT(32 EXPECT_EXIT(
33 std::shared_ptr<msh::SurfaceFactory> factory;33 std::shared_ptr<msh::SurfaceFactory> surface_factory;
34 mir::shell::SessionManager app(factory,34 mir::shell::SessionManager app(surface_factory,
35 std::shared_ptr<msh::SessionContainer>(),35 std::shared_ptr<msh::SessionContainer>(),
36 std::shared_ptr<msh::FocusSequence>(),36 std::shared_ptr<msh::FocusSequence>(),
37 std::shared_ptr<msh::FocusSetter>()),37 std::shared_ptr<msh::FocusSetter>(),
38 std::shared_ptr<msh::InputTargetListener>()),
38 ::testing::KilledBySignal(SIGABRT),39 ::testing::KilledBySignal(SIGABRT),
39 ".*");40 ".*");
40}41}
4142
=== modified file 'tests/integration-tests/input/android/test_android_input_manager.cpp'
--- tests/integration-tests/input/android/test_android_input_manager.cpp 2013-04-10 23:48:23 +0000
+++ tests/integration-tests/input/android/test_android_input_manager.cpp 2013-04-22 16:32:37 +0000
@@ -35,6 +35,7 @@
35#include "mir_test_doubles/stub_surface_target.h"35#include "mir_test_doubles/stub_surface_target.h"
36#include "mir_test/wait_condition.h"36#include "mir_test/wait_condition.h"
37#include "mir_test/event_factory.h"37#include "mir_test/event_factory.h"
38#include "mir_test/event_matchers.h"
3839
39#include <EventHub.h>40#include <EventHub.h>
40#include <InputDispatcher.h>41#include <InputDispatcher.h>
@@ -171,7 +172,7 @@
171struct MockDispatcherPolicy : public mia::EventFilterDispatcherPolicy172struct MockDispatcherPolicy : public mia::EventFilterDispatcherPolicy
172{173{
173 MockDispatcherPolicy(std::shared_ptr<mi::EventFilter> const& filter)174 MockDispatcherPolicy(std::shared_ptr<mi::EventFilter> const& filter)
174 : EventFilterDispatcherPolicy(filter)175 : EventFilterDispatcherPolicy(filter, false)
175 {176 {
176 }177 }
177 MOCK_METHOD3(interceptKeyBeforeDispatching, nsecs_t(droidinput::sp<droidinput::InputWindowHandle> const&,178 MOCK_METHOD3(interceptKeyBeforeDispatching, nsecs_t(droidinput::sp<droidinput::InputWindowHandle> const&,
@@ -211,24 +212,31 @@
211 ON_CALL(viewable_area, view_area())212 ON_CALL(viewable_area, view_area())
212 .WillByDefault(Return(default_view_area));213 .WillByDefault(Return(default_view_area));
213 input_manager = std::make_shared<mia::InputManager>(configuration);214 input_manager = std::make_shared<mia::InputManager>(configuration);
214 input_focus_selector = std::make_shared<mia::DispatcherController>(configuration);215 input_target_listener = std::make_shared<mia::DispatcherController>(configuration);
215216
216 dispatcher_policy = configuration->the_mock_dispatcher_policy();217 dispatcher_policy = configuration->the_mock_dispatcher_policy();
217218
218 }219 }
219220
221 ~AndroidInputManagerDispatcherInterceptSetup()
222 {
223 input_manager->stop();
224 }
225
220 // TODO: It would be nice if it were possible to mock the interface between226 // TODO: It would be nice if it were possible to mock the interface between
221 // droidinput::InputChannel and droidinput::InputDispatcher rather than use227 // droidinput::InputChannel and droidinput::InputDispatcher rather than use
222 // valid fds to allow non-throwing construction of a real input channel.228 // valid fds to allow non-throwing construction of a real input channel.
223 void SetUp()229 void SetUp()
224 {230 {
225 test_input_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
226 input_manager->start();231 input_manager->start();
227 }232 }
228 void TearDown()233
234 int test_fd()
229 {235 {
230 input_manager->stop();236 int fds[2];
231 close(test_input_fd);237 // Closed by droidinput InputChannel on shutdown
238 socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds);
239 return fds[0];
232 }240 }
233241
234 MockEventFilter event_filter;242 MockEventFilter event_filter;
@@ -238,9 +246,7 @@
238 droidinput::sp<MockDispatcherPolicy> dispatcher_policy;246 droidinput::sp<MockDispatcherPolicy> dispatcher_policy;
239247
240 std::shared_ptr<mia::InputManager> input_manager;248 std::shared_ptr<mia::InputManager> input_manager;
241 std::shared_ptr<msh::InputFocusSelector> input_focus_selector;249 std::shared_ptr<msh::InputTargetListener> input_target_listener;
242
243 int test_input_fd;
244};250};
245251
246MATCHER_P(WindowHandleWithInputFd, input_fd, "")252MATCHER_P(WindowHandleWithInputFd, input_fd, "")
@@ -259,14 +265,18 @@
259 mt::WaitCondition wait_condition;265 mt::WaitCondition wait_condition;
260266
261 mtd::StubSessionTarget session;267 mtd::StubSessionTarget session;
262 mtd::StubSurfaceTarget surface(test_input_fd);268
269 auto input_fd = test_fd();
270 mtd::StubSurfaceTarget surface(input_fd);
263271
264 EXPECT_CALL(event_filter, handles(_)).Times(1).WillOnce(Return(false));272 EXPECT_CALL(event_filter, handles(_)).Times(1).WillOnce(Return(false));
265 // We return -1 here to skip publishing of the event (to an unconnected test socket!).273 // We return -1 here to skip publishing of the event (to an unconnected test socket!).
266 EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(test_input_fd), _, _))274 EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(input_fd), _, _))
267 .Times(1).WillOnce(DoAll(mt::WakeUp(&wait_condition), Return(-1)));275 .Times(1).WillOnce(DoAll(mt::WakeUp(&wait_condition), Return(-1)));
268276
269 input_focus_selector->set_input_focus_to(mt::fake_shared(session), mt::fake_shared(surface));277 input_target_listener->input_application_opened(mt::fake_shared(session));
278 input_target_listener->input_surface_opened(mt::fake_shared(session), mt::fake_shared(surface));
279 input_target_listener->focus_changed(mt::fake_shared(surface));
270280
271 fake_event_hub->synthesize_builtin_keyboard_added();281 fake_event_hub->synthesize_builtin_keyboard_added();
272 fake_event_hub->synthesize_device_scan_complete();282 fake_event_hub->synthesize_device_scan_complete();
@@ -275,3 +285,52 @@
275285
276 wait_condition.wait_for_at_most_seconds(1);286 wait_condition.wait_for_at_most_seconds(1);
277}287}
288
289TEST_F(AndroidInputManagerDispatcherInterceptSetup, changing_focus_changes_event_recipient)
290{
291 using namespace ::testing;
292
293 mt::WaitCondition wait1, wait2, wait3;
294
295 mtd::StubSessionTarget session;
296
297 auto input_fd_1 = test_fd();
298 mtd::StubSurfaceTarget surface1(input_fd_1);
299 auto input_fd_2 = test_fd();
300 mtd::StubSurfaceTarget surface2(input_fd_2);
301
302 input_target_listener->input_application_opened(mt::fake_shared(session));
303 input_target_listener->input_surface_opened(mt::fake_shared(session), mt::fake_shared(surface1));
304 input_target_listener->input_surface_opened(mt::fake_shared(session), mt::fake_shared(surface2));
305
306 EXPECT_CALL(event_filter, handles(_)).Times(3).WillRepeatedly(Return(false));
307
308 {
309 InSequence seq;
310
311 EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(input_fd_1), _, _))
312 .Times(1).WillOnce(DoAll(mt::WakeUp(&wait1), Return(-1)));
313 EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(input_fd_2), _, _))
314 .Times(1).WillOnce(DoAll(mt::WakeUp(&wait2), Return(-1)));
315 EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(input_fd_1), _, _))
316 .Times(1).WillOnce(DoAll(mt::WakeUp(&wait3), Return(-1)));
317 }
318
319 fake_event_hub->synthesize_builtin_keyboard_added();
320 fake_event_hub->synthesize_device_scan_complete();
321
322 input_target_listener->focus_changed(mt::fake_shared(surface1));
323 fake_event_hub->synthesize_event(mis::a_key_down_event()
324 .of_scancode(KEY_1));
325 wait1.wait_for_at_most_seconds(1);
326
327 input_target_listener->focus_changed(mt::fake_shared(surface2));
328 fake_event_hub->synthesize_event(mis::a_key_down_event()
329 .of_scancode(KEY_2));
330 wait2.wait_for_at_most_seconds(1);
331
332 input_target_listener->focus_changed(mt::fake_shared(surface1));
333 fake_event_hub->synthesize_event(mis::a_key_down_event()
334 .of_scancode(KEY_3));
335 wait3.wait_for_at_most_seconds(5);
336}
278337
=== modified file 'tests/integration-tests/input/android/test_fake_event_hub_to_event_filter.cpp'
--- tests/integration-tests/input/android/test_fake_event_hub_to_event_filter.cpp 2013-04-02 18:26:40 +0000
+++ tests/integration-tests/input/android/test_fake_event_hub_to_event_filter.cpp 2013-04-22 16:32:37 +0000
@@ -26,6 +26,7 @@
26#include "mir_test_doubles/mock_event_filter.h"26#include "mir_test_doubles/mock_event_filter.h"
27#include "mir_test/wait_condition.h"27#include "mir_test/wait_condition.h"
28#include "mir_test/event_factory.h"28#include "mir_test/event_factory.h"
29#include "mir_test/event_matchers.h"
2930
30#include <InputDispatcher.h>31#include <InputDispatcher.h>
31#include <InputReader.h>32#include <InputReader.h>
@@ -56,7 +57,7 @@
56 void SetUp()57 void SetUp()
57 {58 {
58 event_hub = new mia::FakeEventHub();59 event_hub = new mia::FakeEventHub();
59 dispatcher_policy = new mia::EventFilterDispatcherPolicy(mt::fake_shared(event_filter));60 dispatcher_policy = new mia::EventFilterDispatcherPolicy(mt::fake_shared(event_filter), false);
60 reader_policy = new mia::RudimentaryInputReaderPolicy();61 reader_policy = new mia::RudimentaryInputReaderPolicy();
61 dispatcher = new droidinput::InputDispatcher(dispatcher_policy);62 dispatcher = new droidinput::InputDispatcher(dispatcher_policy);
62 reader = new droidinput::InputReader(event_hub, reader_policy, dispatcher);63 reader = new droidinput::InputReader(event_hub, reader_policy, dispatcher);
6364
=== modified file 'tests/integration-tests/shell/test_session_manager.cpp'
--- tests/integration-tests/shell/test_session_manager.cpp 2013-04-18 00:00:55 +0000
+++ tests/integration-tests/shell/test_session_manager.cpp 2013-04-22 16:32:37 +0000
@@ -33,6 +33,7 @@
33#include "mir_test/fake_shared.h"33#include "mir_test/fake_shared.h"
34#include "mir_test_doubles/mock_surface_factory.h"34#include "mir_test_doubles/mock_surface_factory.h"
35#include "mir_test_doubles/mock_focus_setter.h"35#include "mir_test_doubles/mock_focus_setter.h"
36#include "mir_test_doubles/stub_input_target_listener.h"
3637
37namespace mc = mir::compositor;38namespace mc = mir::compositor;
38namespace mf = mir::frontend;39namespace mf = mir::frontend;
@@ -44,19 +45,22 @@
44TEST(TestSessionManagerAndFocusSelectionStrategy, cycle_focus)45TEST(TestSessionManagerAndFocusSelectionStrategy, cycle_focus)
45{46{
46 using namespace ::testing;47 using namespace ::testing;
48
47 mtd::MockSurfaceFactory surface_factory;49 mtd::MockSurfaceFactory surface_factory;
48 std::shared_ptr<msh::DefaultSessionContainer> container(new msh::DefaultSessionContainer());50 std::shared_ptr<msh::DefaultSessionContainer> container(new msh::DefaultSessionContainer());
49 msh::RegistrationOrderFocusSequence sequence(container);51 msh::RegistrationOrderFocusSequence sequence(container);
50 mtd::MockFocusSetter focus_changer;52 mtd::MockFocusSetter focus_setter;
51 std::shared_ptr<mf::Session> new_session;53 std::shared_ptr<mf::Session> new_session;
54 mtd::StubInputTargetListener input_target_listener;
5255
53 msh::SessionManager session_manager(56 msh::SessionManager session_manager(
54 mt::fake_shared(surface_factory),57 mt::fake_shared(surface_factory),
55 container,58 container,
56 mt::fake_shared(sequence),59 mt::fake_shared(sequence),
57 mt::fake_shared(focus_changer));60 mt::fake_shared(focus_setter),
5861 mt::fake_shared(input_target_listener));
59 EXPECT_CALL(focus_changer, set_focus_to(_)).Times(3);62
63 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);
6064
61 auto session1 = session_manager.open_session("Visual Basic Studio");65 auto session1 = session_manager.open_session("Visual Basic Studio");
62 auto session2 = session_manager.open_session("Microsoft Access");66 auto session2 = session_manager.open_session("Microsoft Access");
@@ -64,9 +68,9 @@
6468
65 {69 {
66 InSequence seq;70 InSequence seq;
67 EXPECT_CALL(focus_changer, set_focus_to(Eq(session1))).Times(1);71 EXPECT_CALL(focus_setter, set_focus_to(Eq(session1))).Times(1);
68 EXPECT_CALL(focus_changer, set_focus_to(Eq(session2))).Times(1);72 EXPECT_CALL(focus_setter, set_focus_to(Eq(session2))).Times(1);
69 EXPECT_CALL(focus_changer, set_focus_to(Eq(session3))).Times(1);73 EXPECT_CALL(focus_setter, set_focus_to(Eq(session3))).Times(1);
70 }74 }
7175
72 session_manager.focus_next();76 session_manager.focus_next();
@@ -77,19 +81,22 @@
77TEST(TestSessionManagerAndFocusSelectionStrategy, closing_applications_transfers_focus)81TEST(TestSessionManagerAndFocusSelectionStrategy, closing_applications_transfers_focus)
78{82{
79 using namespace ::testing;83 using namespace ::testing;
84
80 mtd::MockSurfaceFactory surface_factory;85 mtd::MockSurfaceFactory surface_factory;
81 std::shared_ptr<msh::DefaultSessionContainer> model(new msh::DefaultSessionContainer());86 std::shared_ptr<msh::DefaultSessionContainer> container(new msh::DefaultSessionContainer());
82 msh::RegistrationOrderFocusSequence sequence(model);87 msh::RegistrationOrderFocusSequence sequence(container);
83 mtd::MockFocusSetter focus_changer;88 mtd::MockFocusSetter focus_setter;
84 std::shared_ptr<mf::Session> new_session;89 std::shared_ptr<mf::Session> new_session;
90 mtd::StubInputTargetListener input_target_listener;
8591
86 msh::SessionManager session_manager(92 msh::SessionManager session_manager(
87 mt::fake_shared(surface_factory),93 mt::fake_shared(surface_factory),
88 model,94 container,
89 mt::fake_shared(sequence),95 mt::fake_shared(sequence),
90 mt::fake_shared(focus_changer));96 mt::fake_shared(focus_setter),
97 mt::fake_shared(input_target_listener));
9198
92 EXPECT_CALL(focus_changer, set_focus_to(_)).Times(3);99 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);
93100
94 auto session1 = session_manager.open_session("Visual Basic Studio");101 auto session1 = session_manager.open_session("Visual Basic Studio");
95 auto session2 = session_manager.open_session("Microsoft Access");102 auto session2 = session_manager.open_session("Microsoft Access");
@@ -97,8 +104,8 @@
97104
98 {105 {
99 InSequence seq;106 InSequence seq;
100 EXPECT_CALL(focus_changer, set_focus_to(Eq(session2))).Times(1);107 EXPECT_CALL(focus_setter, set_focus_to(Eq(session2))).Times(1);
101 EXPECT_CALL(focus_changer, set_focus_to(Eq(session1))).Times(1);108 EXPECT_CALL(focus_setter, set_focus_to(Eq(session1))).Times(1);
102 }109 }
103110
104 session_manager.close_session(session3);111 session_manager.close_session(session3);
105112
=== modified file 'tests/mir_test_doubles/fake_event_hub.cpp'
--- tests/mir_test_doubles/fake_event_hub.cpp 2013-03-29 16:51:35 +0000
+++ tests/mir_test_doubles/fake_event_hub.cpp 2013-04-22 16:32:37 +0000
@@ -322,7 +322,7 @@
322void mia::FakeEventHub::synthesize_event(const mis::ButtonParameters &parameters)322void mia::FakeEventHub::synthesize_event(const mis::ButtonParameters &parameters)
323{323{
324 RawEvent event;324 RawEvent event;
325 event.when = 0; // TODO: This may need a timestamp to go over the wire ~racarr325 event.when = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
326 event.type = EV_KEY;326 event.type = EV_KEY;
327 event.code = parameters.button;327 event.code = parameters.button;
328328
@@ -348,7 +348,7 @@
348void mia::FakeEventHub::synthesize_event(const mis::MotionParameters &parameters)348void mia::FakeEventHub::synthesize_event(const mis::MotionParameters &parameters)
349{349{
350 RawEvent event;350 RawEvent event;
351 event.when = 0;351 event.when = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
352 event.type = EV_REL;352 event.type = EV_REL;
353 if (parameters.device_id)353 if (parameters.device_id)
354 event.deviceId = parameters.device_id;354 event.deviceId = parameters.device_id;
355355
=== modified file 'tests/mir_test_framework/testing_server_options.cpp'
--- tests/mir_test_framework/testing_server_options.cpp 2013-04-18 15:20:45 +0000
+++ tests/mir_test_framework/testing_server_options.cpp 2013-04-22 16:32:37 +0000
@@ -29,7 +29,7 @@
29#include "mir/compositor/graphic_buffer_allocator.h"29#include "mir/compositor/graphic_buffer_allocator.h"
30#include "mir/input/input_channel.h"30#include "mir/input/input_channel.h"
31#include "mir/input/input_manager.h"31#include "mir/input/input_manager.h"
32#include "mir/shell/input_focus_selector.h"32#include "mir/input/null_input_target_listener.h"
33#include "src/server/input/android/android_input_manager.h"33#include "src/server/input/android/android_input_manager.h"
34#include "src/server/input/android/android_dispatcher_controller.h"34#include "src/server/input/android/android_dispatcher_controller.h"
3535
@@ -159,14 +159,6 @@
159 }159 }
160};160};
161161
162class StubInputFocusSelector : public msh::InputFocusSelector
163{
164public:
165 void set_input_focus_to(std::shared_ptr<mi::SessionTarget> const& /* session */, std::shared_ptr<mi::SurfaceTarget> const& /* surface */)
166 {
167 }
168};
169
170}162}
171163
172mtf::TestingServerConfiguration::TestingServerConfiguration() :164mtf::TestingServerConfiguration::TestingServerConfiguration() :
@@ -184,14 +176,14 @@
184 return std::make_shared<StubInputManager>();176 return std::make_shared<StubInputManager>();
185}177}
186178
187std::shared_ptr<msh::InputFocusSelector> mtf::TestingServerConfiguration::the_input_focus_selector()179std::shared_ptr<msh::InputTargetListener> mtf::TestingServerConfiguration::the_input_target_listener()
188{180{
189 auto options = the_options();181 auto options = the_options();
190 182
191 if (options->get("tests-use-real-input", false))183 if (options->get("tests-use-real-input", false))
192 return std::make_shared<mia::DispatcherController>(the_input_configuration());184 return std::make_shared<mia::DispatcherController>(the_input_configuration());
193 else185 else
194 return std::make_shared<StubInputFocusSelector>();186 return std::make_shared<mi::NullInputTargetListener>();
195}187}
196188
197std::shared_ptr<mg::Platform> mtf::TestingServerConfiguration::the_graphics_platform()189std::shared_ptr<mg::Platform> mtf::TestingServerConfiguration::the_graphics_platform()
198190
=== modified file 'tests/unit-tests/input/android/test_android_dispatcher_controller.cpp'
--- tests/unit-tests/input/android/test_android_dispatcher_controller.cpp 2013-04-15 14:39:18 +0000
+++ tests/unit-tests/input/android/test_android_dispatcher_controller.cpp 2013-04-22 16:32:37 +0000
@@ -31,6 +31,8 @@
31#include <sys/types.h>31#include <sys/types.h>
32#include <sys/socket.h>32#include <sys/socket.h>
3333
34#include <stdexcept>
35
34namespace mi = mir::input;36namespace mi = mir::input;
35namespace mia = mi::android;37namespace mia = mi::android;
36namespace mt = mir::test;38namespace mt = mir::test;
@@ -47,12 +49,16 @@
47 void SetUp() override49 void SetUp() override
48 {50 {
49 test_input_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);51 test_input_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
52
53 dispatcher = new mtd::MockInputDispatcher();
50 }54 }
51 void TearDown() override55 void TearDown() override
52 {56 {
53 close(test_input_fd);57 close(test_input_fd);
54 }58 }
55 int test_input_fd;59 int test_input_fd;
60 droidinput::sp<mtd::MockInputDispatcher> dispatcher;
61 mtd::MockInputConfiguration config;
56};62};
5763
58static bool64static bool
@@ -104,12 +110,116 @@
104110
105}111}
106112
107TEST_F(AndroidDispatcherControllerFdSetup, set_input_focus)113TEST_F(AndroidDispatcherControllerFdSetup, input_application_opened_behavior)
108{114{
109 using namespace ::testing;115 using namespace ::testing;
110116
111 auto dispatcher = new mtd::MockInputDispatcher(); // We need droidinput::sp117 EXPECT_CALL(config, the_dispatcher()).Times(1)
112 mtd::MockInputConfiguration config;118 .WillOnce(Return(dispatcher));
119 mia::DispatcherController controller(mt::fake_shared(config));
120
121 auto session = std::make_shared<mtd::StubSessionTarget>();
122 controller.input_application_opened(session);
123 EXPECT_THROW({
124 // An application can not be opened twice!
125 controller.input_application_opened(session);
126 }, std::logic_error);
127}
128
129TEST_F(AndroidDispatcherControllerFdSetup, input_application_closed_behavior)
130{
131 using namespace ::testing;
132
133 EXPECT_CALL(config, the_dispatcher()).Times(1)
134 .WillOnce(Return(dispatcher));
135 mia::DispatcherController controller(mt::fake_shared(config));
136
137 auto session = std::make_shared<mtd::StubSessionTarget>();
138 EXPECT_THROW({
139 // We can't close an application which is not open
140 controller.input_application_closed(session);
141 }, std::logic_error);
142 controller.input_application_opened(session);
143 controller.input_application_closed(session);
144 EXPECT_THROW({
145 // Nor can we close an application twice
146 controller.input_application_closed(session);
147 }, std::logic_error);
148}
149
150TEST_F(AndroidDispatcherControllerFdSetup, input_surface_opened_behavior)
151{
152 using namespace ::testing;
153
154 auto session = std::make_shared<mtd::StubSessionTarget>();
155 auto surface = std::make_shared<mtd::StubSurfaceTarget>(test_input_fd);
156
157 EXPECT_CALL(config, the_dispatcher()).Times(1)
158 .WillOnce(Return(dispatcher));
159 EXPECT_CALL(*dispatcher, registerInputChannel(_, WindowHandleFor(session, surface), false)).Times(1)
160 .WillOnce(Return(droidinput::OK));
161
162 mia::DispatcherController controller(mt::fake_shared(config));
163
164 EXPECT_THROW({
165 // We can't open a surface with an unopened session!
166 controller.input_surface_opened(session, surface);
167 }, std::logic_error);
168 controller.input_application_opened(session);
169 controller.input_surface_opened(session, surface);
170 EXPECT_THROW({
171 // We can't open a surface twice
172 controller.input_surface_opened(session, surface);
173 }, std::logic_error);
174}
175
176TEST_F(AndroidDispatcherControllerFdSetup, input_surface_closed_behavior)
177{
178 using namespace ::testing;
179
180 auto session = std::make_shared<mtd::StubSessionTarget>();
181 auto surface = std::make_shared<mtd::StubSurfaceTarget>(test_input_fd);
182
183 EXPECT_CALL(config, the_dispatcher()).Times(1)
184 .WillOnce(Return(dispatcher));
185 EXPECT_CALL(*dispatcher, registerInputChannel(_, WindowHandleFor(session, surface), false)).Times(1)
186 .WillOnce(Return(droidinput::OK));
187 EXPECT_CALL(*dispatcher, unregisterInputChannel(_)).Times(1);
188 mia::DispatcherController controller(mt::fake_shared(config));
189
190 controller.input_application_opened(session);
191
192 EXPECT_THROW({
193 // We can't close a surface which hasn't been opened
194 controller.input_surface_closed(surface);
195 }, std::logic_error);
196 controller.input_surface_opened(session, surface);
197 controller.input_surface_closed(surface);
198 EXPECT_THROW({
199 // Nor can we close a surface twice
200 controller.input_surface_closed(surface);
201 }, std::logic_error);
202}
203
204TEST_F(AndroidDispatcherControllerFdSetup, on_focus_cleared)
205{
206 using namespace ::testing;
207
208 EXPECT_CALL(config, the_dispatcher()).Times(1)
209 .WillOnce(Return(dispatcher));
210
211 EXPECT_CALL(*dispatcher, setFocusedApplication(droidinput::sp<droidinput::InputApplicationHandle>(0))).Times(1);
212 EXPECT_CALL(*dispatcher, setInputWindows(EmptyVector())).Times(1);
213
214 mia::DispatcherController controller(mt::fake_shared(config));
215
216 controller.focus_cleared();
217}
218
219TEST_F(AndroidDispatcherControllerFdSetup, on_focus_changed)
220{
221 using namespace ::testing;
222
113 EXPECT_CALL(config, the_dispatcher()).Times(1)223 EXPECT_CALL(config, the_dispatcher()).Times(1)
114 .WillOnce(Return(dispatcher));224 .WillOnce(Return(dispatcher));
115225
@@ -119,15 +229,30 @@
119 {229 {
120 InSequence seq;230 InSequence seq;
121 EXPECT_CALL(*dispatcher, setFocusedApplication(ApplicationHandleFor(session))).Times(1);231 EXPECT_CALL(*dispatcher, setFocusedApplication(ApplicationHandleFor(session))).Times(1);
122 EXPECT_CALL(*dispatcher, registerInputChannel(_, WindowHandleFor(session, surface), false)).Times(1)
123 .WillOnce(Return(droidinput::OK));
124 EXPECT_CALL(*dispatcher, setInputWindows(VectorContainingWindowHandleFor(session, surface))).Times(1);232 EXPECT_CALL(*dispatcher, setInputWindows(VectorContainingWindowHandleFor(session, surface))).Times(1);
125 EXPECT_CALL(*dispatcher, unregisterInputChannel(_)).Times(1);
126 EXPECT_CALL(*dispatcher, setInputWindows(EmptyVector())).Times(1);
127 }233 }
128234
129 mia::DispatcherController controller(mt::fake_shared(config));235 mia::DispatcherController controller(mt::fake_shared(config));
130236
131 controller.set_input_focus_to(session, surface);237 controller.input_application_opened(session);
132 controller.set_input_focus_to(session, std::shared_ptr<mi::SurfaceTarget>());238 controller.input_surface_opened(session, surface);
239
240 controller.focus_changed(surface);
241}
242
243TEST_F(AndroidDispatcherControllerFdSetup, on_focus_changed_throw_behavior)
244{
245 using namespace ::testing;
246
247 EXPECT_CALL(config, the_dispatcher()).Times(1)
248 .WillOnce(Return(dispatcher));
249
250 auto surface = std::make_shared<mtd::StubSurfaceTarget>(test_input_fd);
251
252 mia::DispatcherController controller(mt::fake_shared(config));
253
254 EXPECT_THROW({
255 // We can't focus surfaces which never opened
256 controller.focus_changed(surface);
257 }, std::logic_error);
133}258}
134259
=== modified file 'tests/unit-tests/input/android/test_android_input_window_handle.cpp'
--- tests/unit-tests/input/android/test_android_input_window_handle.cpp 2013-04-04 11:26:58 +0000
+++ tests/unit-tests/input/android/test_android_input_window_handle.cpp 2013-04-22 16:32:37 +0000
@@ -52,6 +52,7 @@
52struct MockSurfaceTarget : public mi::SurfaceTarget52struct MockSurfaceTarget : public mi::SurfaceTarget
53{53{
54 MOCK_CONST_METHOD0(server_input_fd, int());54 MOCK_CONST_METHOD0(server_input_fd, int());
55 MOCK_CONST_METHOD0(top_left, geom::Point());
55 MOCK_CONST_METHOD0(size, geom::Size());56 MOCK_CONST_METHOD0(size, geom::Size());
56 MOCK_CONST_METHOD0(name, std::string());57 MOCK_CONST_METHOD0(name, std::string());
57};58};
@@ -64,6 +65,7 @@
6465
65 geom::Size const default_surface_size = geom::Size{geom::Width{256},66 geom::Size const default_surface_size = geom::Size{geom::Width{256},
66 geom::Height{256}};67 geom::Height{256}};
68 geom::Point const default_surface_top_left = geom::Point{geom::X{10}, geom::Y{10}};
67 std::string const testing_surface_name = "Test";69 std::string const testing_surface_name = "Test";
6870
69 // We need a real open fd, as InputWindowHandle's constructor will fcntl() it, and71 // We need a real open fd, as InputWindowHandle's constructor will fcntl() it, and
@@ -81,6 +83,8 @@
81 // for touch/pointer events we will need a position83 // for touch/pointer events we will need a position
82 EXPECT_CALL(surface, size()).Times(1)84 EXPECT_CALL(surface, size()).Times(1)
83 .WillOnce(Return(default_surface_size));85 .WillOnce(Return(default_surface_size));
86 EXPECT_CALL(surface, top_left()).Times(1)
87 .WillOnce(Return(default_surface_top_left));
84 EXPECT_CALL(surface, name()).Times(1)88 EXPECT_CALL(surface, name()).Times(1)
85 .WillOnce(Return(testing_surface_name));89 .WillOnce(Return(testing_surface_name));
8690
@@ -93,8 +97,15 @@
9397
94 EXPECT_EQ(testing_server_fd, info->inputChannel->getFd());98 EXPECT_EQ(testing_server_fd, info->inputChannel->getFd());
9599
100 EXPECT_EQ(default_surface_top_left.x.as_uint32_t(), (uint32_t)(info->frameLeft));
101 EXPECT_EQ(default_surface_top_left.y.as_uint32_t(), (uint32_t)(info->frameTop));
96 EXPECT_EQ(default_surface_size.height.as_uint32_t(), (uint32_t)(info->frameRight - info->frameLeft));102 EXPECT_EQ(default_surface_size.height.as_uint32_t(), (uint32_t)(info->frameRight - info->frameLeft));
97 EXPECT_EQ(default_surface_size.height.as_uint32_t(), (uint32_t)(info->frameBottom - info->frameTop));103 EXPECT_EQ(default_surface_size.height.as_uint32_t(), (uint32_t)(info->frameBottom - info->frameTop));
98104
105 EXPECT_EQ(info->frameLeft, info->touchableRegionLeft);
106 EXPECT_EQ(info->frameTop, info->touchableRegionTop);
107 EXPECT_EQ(info->frameRight, info->touchableRegionRight);
108 EXPECT_EQ(info->frameBottom, info->touchableRegionBottom);
109
99 free(filename);110 free(filename);
100}111}
101112
=== modified file 'tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp'
--- tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp 2013-03-22 16:41:59 +0000
+++ tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp 2013-04-22 16:32:37 +0000
@@ -32,12 +32,12 @@
32namespace mt = mir::test;32namespace mt = mir::test;
33namespace mtd = mir::test::doubles;33namespace mtd = mir::test::doubles;
3434
35TEST(EventFilterDispatcherPolicy, offers_events_to_filter)35TEST(EventFilterDispatcherPolicy, offers_key_events_to_filter)
36{36{
37 using namespace ::testing;37 using namespace ::testing;
38 droidinput::KeyEvent ev;38 droidinput::KeyEvent ev;
39 mtd::MockEventFilter filter;39 mtd::MockEventFilter filter;
40 mia::EventFilterDispatcherPolicy policy(mt::fake_shared(filter));40 mia::EventFilterDispatcherPolicy policy(mt::fake_shared(filter), true);
41 uint32_t policy_flags;41 uint32_t policy_flags;
4242
43 EXPECT_CALL(filter, handles(_)).Times(1).WillOnce(Return(false));43 EXPECT_CALL(filter, handles(_)).Times(1).WillOnce(Return(false));
@@ -53,3 +53,16 @@
53 EXPECT_TRUE(policy.filterInputEvent(&ev, 0));53 EXPECT_TRUE(policy.filterInputEvent(&ev, 0));
54}54}
5555
56TEST(EventFilterDispatcherPolicy, motion_events_are_allowed_to_pass_to_clients)
57{
58 using namespace ::testing;
59
60 mtd::MockEventFilter filter;
61 mia::EventFilterDispatcherPolicy policy(mt::fake_shared(filter), true);
62
63 uint32_t policy_flags;
64 policy.interceptMotionBeforeQueueing(0, policy_flags);
65
66 // All motion events are allowed. Of course they could later be removed by the input filter.
67 EXPECT_TRUE(policy_flags & droidinput::POLICY_FLAG_PASS_TO_USER);
68}
5669
=== modified file 'tests/unit-tests/shell/test_application_session.cpp'
--- tests/unit-tests/shell/test_application_session.cpp 2013-04-17 18:18:31 +0000
+++ tests/unit-tests/shell/test_application_session.cpp 2013-04-22 16:32:37 +0000
@@ -22,6 +22,7 @@
22#include "mir_test/fake_shared.h"22#include "mir_test/fake_shared.h"
23#include "mir_test_doubles/mock_surface_factory.h"23#include "mir_test_doubles/mock_surface_factory.h"
24#include "mir_test_doubles/mock_surface.h"24#include "mir_test_doubles/mock_surface.h"
25#include "mir_test_doubles/stub_input_target_listener.h"
25#include "mir_test_doubles/stub_surface_builder.h"26#include "mir_test_doubles/stub_surface_builder.h"
26#include "mir_test_doubles/stub_surface.h"27#include "mir_test_doubles/stub_surface.h"
2728
@@ -51,7 +52,8 @@
51 EXPECT_CALL(surface_factory, create_surface(_));52 EXPECT_CALL(surface_factory, create_surface(_));
52 EXPECT_CALL(*mock_surface, destroy());53 EXPECT_CALL(*mock_surface, destroy());
5354
54 msh::ApplicationSession session(mt::fake_shared(surface_factory), "Foo");55 mtd::StubInputTargetListener input_listener;
56 msh::ApplicationSession session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo");
5557
56 mf::SurfaceCreationParameters params;58 mf::SurfaceCreationParameters params;
57 auto surf = session.create_surface(params);59 auto surf = session.create_surface(params);
@@ -75,7 +77,8 @@
75 .WillOnce(Return(std::make_shared<NiceMock<mtd::MockSurface>>(mt::fake_shared(surface_builder))));77 .WillOnce(Return(std::make_shared<NiceMock<mtd::MockSurface>>(mt::fake_shared(surface_builder))));
76 }78 }
7779
78 msh::ApplicationSession app_session(mt::fake_shared(surface_factory), "Foo");80 mtd::StubInputTargetListener input_listener;
81 msh::ApplicationSession app_session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo");
7982
80 mf::SurfaceCreationParameters params;83 mf::SurfaceCreationParameters params;
81 auto id1 = app_session.create_surface(params);84 auto id1 = app_session.create_surface(params);
@@ -105,7 +108,8 @@
105 mtd::MockSurfaceFactory surface_factory;108 mtd::MockSurfaceFactory surface_factory;
106 ON_CALL(surface_factory, create_surface(_)).WillByDefault(Return(mock_surface));109 ON_CALL(surface_factory, create_surface(_)).WillByDefault(Return(mock_surface));
107110
108 msh::ApplicationSession app_session(mt::fake_shared(surface_factory), "Foo");111 mtd::StubInputTargetListener input_listener;
112 msh::ApplicationSession app_session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo");
109113
110 EXPECT_CALL(surface_factory, create_surface(_));114 EXPECT_CALL(surface_factory, create_surface(_));
111115
@@ -130,7 +134,8 @@
130 using namespace ::testing;134 using namespace ::testing;
131135
132 mtd::MockSurfaceFactory surface_factory;136 mtd::MockSurfaceFactory surface_factory;
133 msh::ApplicationSession app_session(mt::fake_shared(surface_factory), "Foo");137 mtd::StubInputTargetListener input_listener;
138 msh::ApplicationSession app_session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo");
134 mf::SurfaceId invalid_surface_id(1);139 mf::SurfaceId invalid_surface_id(1);
135140
136 EXPECT_THROW({141 EXPECT_THROW({
@@ -143,7 +148,8 @@
143 using namespace ::testing;148 using namespace ::testing;
144149
145 mtd::MockSurfaceFactory surface_factory;150 mtd::MockSurfaceFactory surface_factory;
146 msh::ApplicationSession app_session(mt::fake_shared(surface_factory), "Foo");151 mtd::StubInputTargetListener input_listener;
152 msh::ApplicationSession app_session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo");
147 mf::SurfaceId invalid_surface_id(1);153 mf::SurfaceId invalid_surface_id(1);
148154
149 EXPECT_THROW({155 EXPECT_THROW({
150156
=== modified file 'tests/unit-tests/shell/test_registration_order_focus_sequence.cpp'
--- tests/unit-tests/shell/test_registration_order_focus_sequence.cpp 2013-04-18 00:00:55 +0000
+++ tests/unit-tests/shell/test_registration_order_focus_sequence.cpp 2013-04-22 16:32:37 +0000
@@ -22,8 +22,11 @@
22#include "mir/shell/registration_order_focus_sequence.h"22#include "mir/shell/registration_order_focus_sequence.h"
23#include "mir/frontend/surface_creation_parameters.h"23#include "mir/frontend/surface_creation_parameters.h"
24#include "mir/surfaces/surface.h"24#include "mir/surfaces/surface.h"
25
25#include "mir_test_doubles/mock_buffer_bundle.h"26#include "mir_test_doubles/mock_buffer_bundle.h"
26#include "mir_test_doubles/mock_surface_factory.h"27#include "mir_test_doubles/mock_surface_factory.h"
28#include "mir_test_doubles/stub_input_target_listener.h"
29#include "mir_test/fake_shared.h"
2730
28#include <gmock/gmock.h>31#include <gmock/gmock.h>
29#include <gtest/gtest.h>32#include <gtest/gtest.h>
@@ -32,7 +35,8 @@
32namespace mc = mir::compositor;35namespace mc = mir::compositor;
33namespace msh = mir::shell;36namespace msh = mir::shell;
34namespace ms = mir::surfaces;37namespace ms = mir::surfaces;
35namespace mtd = mir::test::doubles;38namespace mt = mir::test;
39namespace mtd = mt::doubles;
3640
37namespace41namespace
38{42{
@@ -45,6 +49,7 @@
45 }49 }
46 std::shared_ptr<mtd::MockSurfaceFactory> factory;50 std::shared_ptr<mtd::MockSurfaceFactory> factory;
47 std::shared_ptr<msh::DefaultSessionContainer> container;51 std::shared_ptr<msh::DefaultSessionContainer> container;
52 mtd::StubInputTargetListener input_listener;
4853
49 static std::string const testing_app_name1;54 static std::string const testing_app_name1;
50 static std::string const testing_app_name2;55 static std::string const testing_app_name2;
@@ -60,9 +65,9 @@
60{65{
61 using namespace ::testing;66 using namespace ::testing;
6267
63 auto app1 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1);68 auto app1 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1);
64 auto app2 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name2);69 auto app2 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name2);
65 auto app3 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name3);70 auto app3 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name3);
6671
67 container->insert_session(app1);72 container->insert_session(app1);
68 container->insert_session(app2);73 container->insert_session(app2);
@@ -78,9 +83,9 @@
78{83{
79 using namespace ::testing;84 using namespace ::testing;
8085
81 auto app1 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1);86 auto app1 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1);
82 auto app2 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name2);87 auto app2 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name2);
83 auto app3 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name3);88 auto app3 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name3);
84 container->insert_session(app1);89 container->insert_session(app1);
85 container->insert_session(app2);90 container->insert_session(app2);
86 container->insert_session(app3);91 container->insert_session(app3);
@@ -95,7 +100,7 @@
95{100{
96 using namespace ::testing;101 using namespace ::testing;
97102
98 auto app1 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1);103 auto app1 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1);
99 container->insert_session(app1);104 container->insert_session(app1);
100105
101 msh::RegistrationOrderFocusSequence focus_sequence(container);106 msh::RegistrationOrderFocusSequence focus_sequence(container);
@@ -107,8 +112,8 @@
107{112{
108 using namespace ::testing;113 using namespace ::testing;
109114
110 auto app1 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1);115 auto app1 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1);
111 auto app2 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name2);116 auto app2 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name2);
112 auto null_session = std::shared_ptr<msh::ApplicationSession>();117 auto null_session = std::shared_ptr<msh::ApplicationSession>();
113118
114 msh::RegistrationOrderFocusSequence focus_sequence(container);119 msh::RegistrationOrderFocusSequence focus_sequence(container);
@@ -124,7 +129,7 @@
124{129{
125 using namespace ::testing;130 using namespace ::testing;
126131
127 auto invalid_session = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1);132 auto invalid_session = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1);
128 auto null_session = std::shared_ptr<msh::ApplicationSession>();133 auto null_session = std::shared_ptr<msh::ApplicationSession>();
129134
130 msh::RegistrationOrderFocusSequence focus_sequence(container);135 msh::RegistrationOrderFocusSequence focus_sequence(container);
131136
=== modified file 'tests/unit-tests/shell/test_session_manager.cpp'
--- tests/unit-tests/shell/test_session_manager.cpp 2013-04-18 22:29:24 +0000
+++ tests/unit-tests/shell/test_session_manager.cpp 2013-04-22 16:32:37 +0000
@@ -21,15 +21,19 @@
21#include "mir/shell/session_manager.h"21#include "mir/shell/session_manager.h"
22#include "mir/shell/default_session_container.h"22#include "mir/shell/default_session_container.h"
23#include "mir/shell/session.h"23#include "mir/shell/session.h"
24#include "mir/shell/input_target_listener.h"
24#include "mir/frontend/surface_creation_parameters.h"25#include "mir/frontend/surface_creation_parameters.h"
25#include "mir/surfaces/surface.h"26#include "mir/surfaces/surface.h"
26#include "mir/input/input_channel.h"27#include "mir/input/input_channel.h"
28
29#include "mir_test/fake_shared.h"
27#include "mir_test_doubles/mock_buffer_bundle.h"30#include "mir_test_doubles/mock_buffer_bundle.h"
28#include "mir_test/fake_shared.h"
29#include "mir_test_doubles/mock_surface_factory.h"31#include "mir_test_doubles/mock_surface_factory.h"
30#include "mir_test_doubles/mock_focus_setter.h"32#include "mir_test_doubles/mock_focus_setter.h"
31#include "mir_test_doubles/null_buffer_bundle.h"33#include "mir_test_doubles/null_buffer_bundle.h"
32#include "mir_test_doubles/stub_surface_builder.h"34#include "mir_test_doubles/stub_surface_builder.h"
35#include "mir_test_doubles/stub_input_target_listener.h"
36#include "mir_test_doubles/mock_input_target_listener.h"
3337
34#include "mir/shell/surface.h"38#include "mir/shell/surface.h"
3539
@@ -56,7 +60,7 @@
56 ~MockSessionContainer() noexcept {}60 ~MockSessionContainer() noexcept {}
57};61};
5862
59struct MockFocusSequence: public msh::FocusSequence63struct MockFocusSequence : public msh::FocusSequence
60{64{
61 MOCK_CONST_METHOD1(successor_of, std::shared_ptr<msh::Session>(std::shared_ptr<msh::Session> const&));65 MOCK_CONST_METHOD1(successor_of, std::shared_ptr<msh::Session>(std::shared_ptr<msh::Session> const&));
62 MOCK_CONST_METHOD1(predecessor_of, std::shared_ptr<msh::Session>(std::shared_ptr<msh::Session> const&));66 MOCK_CONST_METHOD1(predecessor_of, std::shared_ptr<msh::Session>(std::shared_ptr<msh::Session> const&));
@@ -68,16 +72,18 @@
68 SessionManagerSetup()72 SessionManagerSetup()
69 : session_manager(mt::fake_shared(surface_factory),73 : session_manager(mt::fake_shared(surface_factory),
70 mt::fake_shared(container),74 mt::fake_shared(container),
71 mt::fake_shared(sequence),75 mt::fake_shared(focus_sequence),
72 mt::fake_shared(focus_setter))76 mt::fake_shared(focus_setter),
77 mt::fake_shared(input_target_listener))
73 {78 {
74 }79 }
7580
76 mtd::StubSurfaceBuilder surface_builder;81 mtd::StubSurfaceBuilder surface_builder;
77 mtd::MockSurfaceFactory surface_factory;82 mtd::MockSurfaceFactory surface_factory;
78 testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub83 testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub
79 MockFocusSequence sequence;84 MockFocusSequence focus_sequence;
80 testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub85 testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub
86 mtd::StubInputTargetListener input_target_listener;
8187
82 msh::SessionManager session_manager;88 msh::SessionManager session_manager;
83};89};
@@ -93,7 +99,7 @@
93 EXPECT_CALL(focus_setter, set_focus_to(_));99 EXPECT_CALL(focus_setter, set_focus_to(_));
94 EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<msh::Session>())).Times(1);100 EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<msh::Session>())).Times(1);
95101
96 EXPECT_CALL(sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>())));102 EXPECT_CALL(focus_sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>())));
97103
98 auto session = session_manager.open_session("Visual Basic Studio");104 auto session = session_manager.open_session("Visual Basic Studio");
99 session_manager.close_session(session);105 session_manager.close_session(session);
@@ -118,7 +124,7 @@
118 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(1);124 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(1);
119 EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<msh::Session>())).Times(1);125 EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<msh::Session>())).Times(1);
120126
121 EXPECT_CALL(sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>())));127 EXPECT_CALL(focus_sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>())));
122128
123 auto session = session_manager.open_session("Visual Basic Studio");129 auto session = session_manager.open_session("Visual Basic Studio");
124 session->create_surface(mf::a_surface().of_size(geom::Size{geom::Width{1024}, geom::Height{768}}));130 session->create_surface(mf::a_surface().of_size(geom::Size{geom::Width{1024}, geom::Height{768}}));
@@ -164,7 +170,7 @@
164 session_manager.tag_session_with_lightdm_id(session1, 1);170 session_manager.tag_session_with_lightdm_id(session1, 1);
165 session_manager.focus_session_with_lightdm_id(1);171 session_manager.focus_session_with_lightdm_id(1);
166172
167 EXPECT_CALL(sequence, default_focus()).WillOnce(Return(shell_session2));173 EXPECT_CALL(focus_sequence, default_focus()).WillOnce(Return(shell_session2));
168 EXPECT_CALL(focus_setter, set_focus_to(Eq(shell_session2)));174 EXPECT_CALL(focus_setter, set_focus_to(Eq(shell_session2)));
169175
170 session_manager.close_session(session1);176 session_manager.close_session(session1);
@@ -193,3 +199,61 @@
193 session_manager.create_surface_for(session1, mf::a_surface());199 session_manager.create_surface_for(session1, mf::a_surface());
194}200}
195201
202namespace
203{
204
205struct SessionManagerInputTargetListenerSetup : public testing::Test
206{
207 SessionManagerInputTargetListenerSetup()
208 : session_manager(mt::fake_shared(surface_factory),
209 mt::fake_shared(container),
210 mt::fake_shared(focus_sequence),
211 mt::fake_shared(focus_setter),
212 mt::fake_shared(input_target_listener))
213 {
214 }
215
216 mtd::StubSurfaceBuilder surface_builder;
217 mtd::MockSurfaceFactory surface_factory;
218 testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub
219 testing::NiceMock<MockFocusSequence> focus_sequence;
220 testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub
221 mtd::MockInputTargetListener input_target_listener;
222
223 msh::SessionManager session_manager;
224};
225
226}
227
228TEST_F(SessionManagerInputTargetListenerSetup, listener_is_notified_of_session_and_surfacelifecycle)
229{
230 using namespace ::testing;
231
232 std::shared_ptr<mi::InputChannel> null_input_channel;
233 ON_CALL(surface_factory, create_surface(_)).WillByDefault(
234 Return(std::make_shared<msh::Surface>(
235 mt::fake_shared(surface_builder),
236 mf::a_surface(),
237 null_input_channel)));
238
239 EXPECT_CALL(focus_sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>())));
240 {
241 InSequence seq;
242
243 EXPECT_CALL(input_target_listener, input_application_opened(_))
244 .Times(1);
245 EXPECT_CALL(input_target_listener, input_surface_opened(_, _)).Times(1);
246 EXPECT_CALL(input_target_listener, focus_changed(_)).Times(1);
247 EXPECT_CALL(input_target_listener, input_surface_closed(_)).Times(1);
248 EXPECT_CALL(input_target_listener, input_application_closed(_))
249 .Times(1);
250 EXPECT_CALL(input_target_listener, focus_cleared()).Times(1);
251 }
252
253 {
254 auto session = session_manager.open_session("test");
255 auto surf = session_manager.create_surface_for(session, mf::a_surface());
256 session->destroy_surface(surf);
257 session_manager.close_session(session);
258 }
259}
196260
=== modified file 'tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp'
--- tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp 2013-04-19 15:33:04 +0000
+++ tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp 2013-04-22 16:32:37 +0000
@@ -27,7 +27,6 @@
27#include "mir_test_doubles/mock_buffer_bundle.h"27#include "mir_test_doubles/mock_buffer_bundle.h"
28#include "mir_test/fake_shared.h"28#include "mir_test/fake_shared.h"
29#include "mir_test_doubles/mock_surface_factory.h"29#include "mir_test_doubles/mock_surface_factory.h"
30#include "mir_test_doubles/mock_input_focus_selector.h"
31#include "mir_test_doubles/stub_surface.h"30#include "mir_test_doubles/stub_surface.h"
32#include "mir_test_doubles/mock_surface.h"31#include "mir_test_doubles/mock_surface.h"
33#include "mir_test_doubles/stub_surface_builder.h"32#include "mir_test_doubles/stub_surface_builder.h"
@@ -64,8 +63,6 @@
64{63{
65 using namespace ::testing;64 using namespace ::testing;
6665
67 NiceMock<mtd::MockInputFocusSelector> input_focus_selector;
68
69 NiceMock<MockShellSession> app1, app2, app3;66 NiceMock<MockShellSession> app1, app2, app3;
70 msh::DefaultSessionContainer model;67 msh::DefaultSessionContainer model;
7168
@@ -73,7 +70,7 @@
73 ON_CALL(app2, default_surface()).WillByDefault(Return(std::shared_ptr<msh::Surface>()));70 ON_CALL(app2, default_surface()).WillByDefault(Return(std::shared_ptr<msh::Surface>()));
74 ON_CALL(app3, default_surface()).WillByDefault(Return(std::shared_ptr<msh::Surface>()));71 ON_CALL(app3, default_surface()).WillByDefault(Return(std::shared_ptr<msh::Surface>()));
7572
76 msh::SingleVisibilityFocusMechanism focus_mechanism(mt::fake_shared(model), mt::fake_shared(input_focus_selector));73 msh::SingleVisibilityFocusMechanism focus_mechanism(mt::fake_shared(model));
7774
78 EXPECT_CALL(app1, show()).Times(1);75 EXPECT_CALL(app1, show()).Times(1);
79 EXPECT_CALL(app2, hide()).Times(1);76 EXPECT_CALL(app2, hide()).Times(1);
@@ -89,23 +86,3 @@
8986
90 focus_mechanism.set_focus_to(mt::fake_shared(app1));87 focus_mechanism.set_focus_to(mt::fake_shared(app1));
91}88}
92
93TEST(SingleVisibilityFocusMechanism, mechanism_sets_input_focus_from_default_surface)
94{
95 using namespace ::testing;
96
97 mtd::MockInputFocusSelector input_focus_selector;
98 msh::DefaultSessionContainer model;
99 auto session = std::make_shared<NiceMock<MockShellSession>>();
100 auto surface = std::make_shared<mtd::MockSurface>(std::make_shared<mtd::StubSurfaceBuilder>());
101
102 msh::SingleVisibilityFocusMechanism focus_mechanism(mt::fake_shared(model), mt::fake_shared(input_focus_selector));
103
104 EXPECT_CALL(*session, default_surface()).Times(1).WillOnce(Return(surface));
105
106 EXPECT_CALL(input_focus_selector, set_input_focus_to(Eq(session), Eq(surface))).Times(1);
107
108 model.insert_session(session);
109 focus_mechanism.set_focus_to(session);
110}
111
11289
=== modified file 'tests/unit-tests/shell/test_surface.cpp'
--- tests/unit-tests/shell/test_surface.cpp 2013-04-16 17:42:26 +0000
+++ tests/unit-tests/shell/test_surface.cpp 2013-04-22 16:32:37 +0000
@@ -220,6 +220,24 @@
220 }, std::runtime_error);220 }, std::runtime_error);
221}221}
222222
223TEST_F(ShellSurface, top_left_throw_behavior)
224{
225 msh::Surface test(
226 mt::fake_shared(surface_builder),
227 mf::a_surface(),
228 null_input_channel);
229
230 EXPECT_NO_THROW({
231 test.top_left();
232 });
233
234 surface_builder.reset_surface();
235
236 EXPECT_THROW({
237 test.top_left();
238 }, std::runtime_error);
239}
240
223TEST_F(ShellSurface, name_throw_behavior)241TEST_F(ShellSurface, name_throw_behavior)
224{242{
225 msh::Surface test(243 msh::Surface test(
226244
=== modified file 'tests/unit-tests/shell/test_the_session_container_implementation.cpp'
--- tests/unit-tests/shell/test_the_session_container_implementation.cpp 2013-04-18 00:00:55 +0000
+++ tests/unit-tests/shell/test_the_session_container_implementation.cpp 2013-04-22 16:32:37 +0000
@@ -22,6 +22,7 @@
22#include "mir/frontend/surface_creation_parameters.h"22#include "mir/frontend/surface_creation_parameters.h"
23#include "mir/surfaces/surface.h"23#include "mir/surfaces/surface.h"
24#include "mir_test_doubles/mock_buffer_bundle.h"24#include "mir_test_doubles/mock_buffer_bundle.h"
25#include "mir_test_doubles/stub_input_target_listener.h"
25#include "mir_test_doubles/mock_surface_factory.h"26#include "mir_test_doubles/mock_surface_factory.h"
2627
27#include <gmock/gmock.h>28#include <gmock/gmock.h>
@@ -38,8 +39,10 @@
38 auto factory = std::make_shared<mtd::MockSurfaceFactory>();39 auto factory = std::make_shared<mtd::MockSurfaceFactory>();
39 msh::DefaultSessionContainer container;40 msh::DefaultSessionContainer container;
4041
41 container.insert_session(std::make_shared<msh::ApplicationSession>(factory, "Visual Studio 7"));42 container.insert_session(std::make_shared<msh::ApplicationSession>(factory, std::make_shared<mtd::StubInputTargetListener>(),
42 container.insert_session(std::make_shared<msh::ApplicationSession>(factory, "Visual Studio 8"));43 "Visual Studio 7"));
44 container.insert_session(std::make_shared<msh::ApplicationSession>(factory, std::make_shared<mtd::StubInputTargetListener>(),
45 "Visual Studio 8"));
4346
44 struct local47 struct local
45 {48 {
@@ -64,8 +67,8 @@
64 auto factory = std::make_shared<mtd::MockSurfaceFactory>();67 auto factory = std::make_shared<mtd::MockSurfaceFactory>();
65 msh::DefaultSessionContainer container;68 msh::DefaultSessionContainer container;
6669
67 auto session = std::make_shared<msh::ApplicationSession>(factory,70 auto session = std::make_shared<msh::ApplicationSession>(factory, std::make_shared<mtd::StubInputTargetListener>(),
68 "Visual Studio 7");71 "Visual Studio 7");
69 EXPECT_THROW({72 EXPECT_THROW({
70 container.remove_session(session);73 container.remove_session(session);
71 }, std::logic_error);74 }, std::logic_error);

Subscribers

People subscribed via source and target branches