Mir

Merge lp:~robertcarr/mir/improve-input-manager-testing into lp:~mir-team/mir/trunk

Proposed by Robert Carr
Status: Merged
Approved by: Alexandros Frantzis
Approved revision: no longer in the source branch.
Merged at revision: 474
Proposed branch: lp:~robertcarr/mir/improve-input-manager-testing
Merge into: lp:~mir-team/mir/trunk
Diff against target: 1210 lines (+814/-101)
17 files modified
3rd_party/android-deps/std/Vector.h (+1/-1)
include/mir/cached_ptr.h (+48/-0)
include/mir/default_server_configuration.h (+1/-23)
include/mir_test/fake_event_hub_input_configuration.h (+80/-0)
src/input/android/CMakeLists.txt (+1/-0)
src/input/android/android_input_configuration.h (+61/-0)
src/input/android/android_input_manager.cpp (+17/-30)
src/input/android/android_input_manager.h (+7/-17)
src/input/android/android_input_thread.h (+47/-0)
src/input/android/default_android_input_configuration.cpp (+149/-0)
src/input/android/default_android_input_configuration.h (+117/-0)
tests/integration-tests/input/android/test_android_cursor_listener.cpp (+16/-11)
tests/integration-tests/input/android/test_android_input_manager.cpp (+21/-19)
tests/mir_test_doubles/CMakeLists.txt (+1/-0)
tests/mir_test_doubles/fake_event_hub_input_configuration.cpp (+48/-0)
tests/unit-tests/input/android/CMakeLists.txt (+1/-0)
tests/unit-tests/input/android/test_android_input_manager.cpp (+198/-0)
To merge this branch: bzr merge lp:~robertcarr/mir/improve-input-manager-testing
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Alexandros Frantzis (community) Approve
Alan Griffiths Approve
Review via email: mp+151865@code.launchpad.net

Commit message

Extract dependencies of mia::InputManager in to mia::InputConfiguration interface (with mia::DefaultInputConfiguration implementation).

Description of the change

This branch improves the testability of the InputManager wrt to the Input stack by isolating input components through an InputConfiguration object (Input input input input!).

New test is tests/unit-tests/input/android/test_android_input_manager.cpp

This is a lot of refactoring for a pretty trivial test at the moment but important when the interaction with the dispatcher becomes more complex (i.e. setInputWindows for client side input).

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

827 + fake_event_hub = dynamic_cast<mia::FakeEventHub *>(configuration->the_event_hub().get()); // For convenience
890 + fake_event_hub = dynamic_cast<mia::FakeEventHub *>(configuration->the_event_hub().get()); // For convenience

It would be cleaner to have a mia::FakeEventHub& FakeEventHubInputConfiguration::the_fake_event_hub() method, and use it to access the underlying fake object.

376 std::shared_ptr<mi::InputManager> mi::create_input_manager(

Would it make sense for mi::create_input_manager() to accept a mi::InputConfiguration object, so that it could be configured externally, or is the input configuration just an internal convenience/testability enhancement?

1057 +#include "mir/input/cursor_listener.h"
1084 +static const std::shared_ptr<mi::CursorListener> null_cursor_listener{};
1085 +static std::initializer_list<std::shared_ptr<mi::EventFilter> const> empty_event_filters{};

Are these used somewhere?

1086 +static const geom::Rectangle default_view_area =

Is this useful outside the test fixture construction?

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

>> It would be cleaner to have a mia::FakeEventHub& FakeEventHubInputConfiguration::the_fake_event_hub()
>> method, and use it to access the underlying fake object.

Yes. Had to use mia::FakeEventHub* due to deleted assignment on android::RefBase however.

376 std::shared_ptr<mi::InputManager> mi::create_input_manager(
I don't think so I think it accepts parameters to create the configuration and the configuration is an internal object. Maybe this will change when we have input options.

>> 1057 +#include "mir/input/cursor_listener.h"
>> 1084 +static const std::shared_ptr<mi::CursorListener> null_cursor_listener{};
>> 1085 +static std::initializer_list<std::shared_ptr<mi::EventFilter> const> empty_event_filters{};
Gone!

>> 1086 +static const geom::Rectangle default_view_area =

Moved!

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

123 + mir::CachedPtr<frontend::Communicator> communicator;
...

Adding "mir::" is pointless noise.

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

>> Adding "mir::" is pointless noise.

Removed

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

include/mir/cached_ptr.h etc.

copyright header should be LGPL

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

Fixed copyright headers

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

LGTM

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

Looks good.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-deps/std/Vector.h'
2--- 3rd_party/android-deps/std/Vector.h 2013-03-04 16:23:13 +0000
3+++ 3rd_party/android-deps/std/Vector.h 2013-03-06 17:03:21 +0000
4@@ -56,7 +56,7 @@
5 * Constructors and destructors
6 */
7 Vector() = default;
8- Vector(const Vector<ValueType>& rhs) = default;
9+ Vector(const Vector<ValueType>& /* rhs */) = default;
10 // explicit Vector(const SortedVector<ValueType>& rhs);
11 virtual ~Vector() {}
12
13
14=== added file 'include/mir/cached_ptr.h'
15--- include/mir/cached_ptr.h 1970-01-01 00:00:00 +0000
16+++ include/mir/cached_ptr.h 2013-03-06 17:03:21 +0000
17@@ -0,0 +1,48 @@
18+/*
19+ * Copyright © 2013 Canonical Ltd.
20+ *
21+ * This program is free software: you can redistribute it and/or modify it
22+ * under the terms of the GNU Lesser General Public License version 3,
23+ * as published by the Free Software Foundation.
24+ *
25+ * This program is distributed in the hope that it will be useful,
26+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28+ * GNU General Public License for more details.
29+ *
30+ * You should have received a copy of the GNU Lesser General Public License
31+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
32+ *
33+ * Authored by: Robert Carr <robert.carr@canonical.com>
34+ */
35+
36+#ifndef MIR_CACHED_PTR_H_
37+#define MIR_CACHED_PTR_H_
38+
39+#include <functional>
40+#include <memory>
41+
42+namespace mir
43+{
44+template<typename Type>
45+class CachedPtr
46+{
47+ std::weak_ptr<Type> cache;
48+ CachedPtr(CachedPtr const&) = delete;
49+ CachedPtr& operator=(CachedPtr const&) = delete;
50+public:
51+ CachedPtr() = default;
52+
53+ std::shared_ptr<Type> operator()(std::function<std::shared_ptr<Type>()> make)
54+ {
55+ auto result = cache.lock();
56+ if (!result)
57+ {
58+ cache = result = make();
59+ }
60+ return result;
61+ }
62+};
63+} // namespace mir
64+
65+#endif // MIR_CACHED_PTR_H_
66
67=== modified file 'include/mir/default_server_configuration.h'
68--- include/mir/default_server_configuration.h 2013-03-05 18:29:19 +0000
69+++ include/mir/default_server_configuration.h 2013-03-06 17:03:21 +0000
70@@ -18,6 +18,7 @@
71 #ifndef MIR_DEFAULT_SERVER_CONFIGURATION_H_
72 #define MIR_DEFAULT_SERVER_CONFIGURATION_H_
73
74+#include "mir/cached_ptr.h"
75 #include "mir/server_configuration.h"
76 #include "mir/options/program_option.h"
77
78@@ -108,29 +109,6 @@
79 protected:
80 virtual std::shared_ptr<options::Option> the_options() const;
81
82- template<typename Type>
83- class CachedPtr
84- {
85- std::weak_ptr<Type> cache;
86-
87- CachedPtr(CachedPtr const&) = delete;
88- CachedPtr& operator=(CachedPtr const&) = delete;
89- public:
90- CachedPtr() = default;
91-
92- std::shared_ptr<Type> operator()(std::function<std::shared_ptr<Type>()> make)
93- {
94- auto result = cache.lock();
95- if (!result)
96- {
97- cache = result = make();
98- }
99-
100- return result;
101-
102- }
103- };
104-
105 CachedPtr<frontend::Communicator> communicator;
106 CachedPtr<sessions::SessionStore> session_store;
107 CachedPtr<input::InputManager> input_manager;
108
109=== added file 'include/mir_test/fake_event_hub_input_configuration.h'
110--- include/mir_test/fake_event_hub_input_configuration.h 1970-01-01 00:00:00 +0000
111+++ include/mir_test/fake_event_hub_input_configuration.h 2013-03-06 17:03:21 +0000
112@@ -0,0 +1,80 @@
113+/*
114+ * Copyright © 2013 Canonical Ltd.
115+ *
116+ * This program is free software: you can redistribute it and/or modify it
117+ * under the terms of the GNU Lesser General Public License version 3,
118+ * as published by the Free Software Foundation.
119+ *
120+ * This program is distributed in the hope that it will be useful,
121+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
122+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
123+ * GNU General Public License for more details.
124+ *
125+ * You should have received a copy of the GNU Lesser General Public License
126+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
127+ *
128+ * Author: Robert Carr <robert.carr@canonical.com>
129+ */
130+
131+#ifndef MIR_TEST_DOUBLES_FAKE_EVENT_HUB_INPUT_CONFIGURATION_H_
132+#define MIR_TEST_DOUBLES_FAKE_EVENT_HUB_INPUT_CONFIGURATION_H_
133+
134+#include "src/input/android/default_android_input_configuration.h"
135+
136+#include <utils/StrongPointer.h>
137+
138+#include <initializer_list>
139+
140+namespace droidinput = android;
141+
142+namespace android
143+{
144+class EventHubInterface;
145+}
146+
147+namespace mir
148+{
149+namespace graphics
150+{
151+class ViewableArea;
152+}
153+namespace input
154+{
155+class CursorListener;
156+class EventFilter;
157+
158+namespace android
159+{
160+class FakeEventHub;
161+}
162+}
163+namespace test
164+{
165+namespace doubles
166+{
167+
168+class FakeEventHubInputConfiguration : public input::android::DefaultInputConfiguration
169+{
170+public:
171+ FakeEventHubInputConfiguration(std::initializer_list<std::shared_ptr<mir::input::EventFilter> const> const& filters,
172+ std::shared_ptr<mir::graphics::ViewableArea> const& view_area,
173+ std::shared_ptr<mir::input::CursorListener> const& cursor_listener);
174+ virtual ~FakeEventHubInputConfiguration();
175+
176+ droidinput::sp<droidinput::EventHubInterface> the_event_hub();
177+ input::android::FakeEventHub* the_fake_event_hub();
178+
179+
180+protected:
181+ FakeEventHubInputConfiguration(FakeEventHubInputConfiguration const&) = delete;
182+ FakeEventHubInputConfiguration& operator=(FakeEventHubInputConfiguration const&) = delete;
183+
184+private:
185+ droidinput::sp<input::android::FakeEventHub> event_hub;
186+};
187+
188+}
189+}
190+} // namespace mir
191+
192+#endif /* MIR_TEST_DOUBLES_FAKE_EVENT_HUB_INPUT_CONFIGURATION_H_ */
193
194=== modified file 'src/input/android/CMakeLists.txt'
195--- src/input/android/CMakeLists.txt 2013-03-04 15:54:45 +0000
196+++ src/input/android/CMakeLists.txt 2013-03-06 17:03:21 +0000
197@@ -6,6 +6,7 @@
198 ${CMAKE_CURRENT_SOURCE_DIR}/android_input_lexicon.cpp
199 ${CMAKE_CURRENT_SOURCE_DIR}/rudimentary_input_reader_policy.cpp
200 ${CMAKE_CURRENT_SOURCE_DIR}/event_filter_dispatcher_policy.cpp
201+ ${CMAKE_CURRENT_SOURCE_DIR}/default_android_input_configuration.cpp
202 )
203
204 set(
205
206=== added file 'src/input/android/android_input_configuration.h'
207--- src/input/android/android_input_configuration.h 1970-01-01 00:00:00 +0000
208+++ src/input/android/android_input_configuration.h 2013-03-06 17:03:21 +0000
209@@ -0,0 +1,61 @@
210+/*
211+ * Copyright © 2013 Canonical Ltd.
212+ *
213+ * This program is free software: you can redistribute it and/or modify it
214+ * under the terms of the GNU Lesser General Public License version 3,
215+ * as published by the Free Software Foundation.
216+ *
217+ * This program is distributed in the hope that it will be useful,
218+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
219+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
220+ * GNU General Public License for more details.
221+ *
222+ * You should have received a copy of the GNU Lesser General Public License
223+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
224+ *
225+ * Authored by: Robert Carr <robert.carr@canonical.com>
226+ */
227+
228+#ifndef MIR_INPUT_ANDROID_INPUT_CONFIGURATION_H_
229+#define MIR_INPUT_ANDROID_INPUT_CONFIGURATION_H_
230+
231+#include <utils/StrongPointer.h>
232+
233+#include <memory>
234+
235+namespace droidinput = android;
236+
237+namespace android
238+{
239+class EventHubInterface;
240+class InputDispatcherInterface;
241+}
242+
243+namespace mir
244+{
245+namespace input
246+{
247+namespace android
248+{
249+class InputThread;
250+
251+class InputConfiguration
252+{
253+public:
254+ virtual ~InputConfiguration() {}
255+
256+ virtual droidinput::sp<droidinput::EventHubInterface> the_event_hub() = 0;
257+ virtual droidinput::sp<droidinput::InputDispatcherInterface> the_dispatcher() = 0;
258+ virtual std::shared_ptr<InputThread> the_dispatcher_thread() = 0;
259+ virtual std::shared_ptr<InputThread> the_reader_thread() = 0;
260+
261+protected:
262+ InputConfiguration() = default;
263+ InputConfiguration(InputConfiguration const&) = delete;
264+ InputConfiguration& operator=(InputConfiguration const&) = delete;
265+};
266+}
267+}
268+} // namespace mir
269+
270+#endif // MIR_INPUT_ANDROID_INPUT_CONFIGURATION_H_
271
272=== modified file 'src/input/android/android_input_manager.cpp'
273--- src/input/android/android_input_manager.cpp 2013-03-04 16:02:02 +0000
274+++ src/input/android/android_input_manager.cpp 2013-03-06 17:03:21 +0000
275@@ -21,12 +21,12 @@
276
277 #include "android_input_manager.h"
278 #include "android_input_constants.h"
279-#include "event_filter_dispatcher_policy.h"
280-#include "android_input_reader_policy.h"
281+#include "android_input_configuration.h"
282+#include "android_input_thread.h"
283+#include "default_android_input_configuration.h"
284
285 #include <EventHub.h>
286 #include <InputDispatcher.h>
287-#include <InputReader.h>
288
289 #include <memory>
290 #include <vector>
291@@ -35,24 +35,12 @@
292 namespace mi = mir::input;
293 namespace mia = mi::android;
294
295-mia::InputManager::InputManager(
296- const droidinput::sp<droidinput::EventHubInterface>& event_hub,
297- const std::initializer_list<std::shared_ptr<mi::EventFilter> const>& filters,
298- std::shared_ptr<mg::ViewableArea> const& view_area,
299- std::shared_ptr<mi::CursorListener> const& cursor_listener)
300- : event_hub(event_hub),
301- filter_chain(std::make_shared<mi::EventFilterChain>(filters)),
302- dispatcher(new droidinput::InputDispatcher(
303- new mia::EventFilterDispatcherPolicy(filter_chain))),
304- reader(new droidinput::InputReader(
305- event_hub,
306- new mia::InputReaderPolicy(view_area, cursor_listener),
307- dispatcher)),
308- reader_thread(new droidinput::InputReaderThread(reader)),
309- dispatcher_thread(new droidinput::InputDispatcherThread(dispatcher))
310+mia::InputManager::InputManager(std::shared_ptr<mia::InputConfiguration> const& config)
311+ : event_hub(config->the_event_hub()),
312+ dispatcher(config->the_dispatcher()),
313+ reader_thread(config->the_reader_thread()),
314+ dispatcher_thread(config->the_dispatcher_thread())
315 {
316- dispatcher->setInputDispatchMode(mia::DispatchEnabled, mia::DispatchUnfrozen);
317- dispatcher->setInputFilterEnabled(true);
318 }
319
320 mia::InputManager::~InputManager()
321@@ -61,19 +49,22 @@
322
323 void mia::InputManager::stop()
324 {
325- dispatcher_thread->requestExit();
326+ dispatcher_thread->request_stop();
327 dispatcher->setInputDispatchMode(mia::DispatchDisabled, mia::DispatchFrozen);
328 dispatcher_thread->join();
329
330- reader_thread->requestExit();
331+ reader_thread->request_stop();
332 event_hub->wake();
333 reader_thread->join();
334 }
335
336 void mia::InputManager::start()
337 {
338- reader_thread->run("InputReader", droidinput::PRIORITY_URGENT_DISPLAY);
339- dispatcher_thread->run("InputDispatcher", droidinput::PRIORITY_URGENT_DISPLAY);
340+ dispatcher->setInputDispatchMode(mia::DispatchEnabled, mia::DispatchUnfrozen);
341+ dispatcher->setInputFilterEnabled(true);
342+
343+ reader_thread->start();
344+ dispatcher_thread->start();
345 }
346
347 std::shared_ptr<mi::InputManager> mi::create_input_manager(
348@@ -81,11 +72,7 @@
349 std::shared_ptr<mg::ViewableArea> const& view_area)
350 {
351 static const std::shared_ptr<mi::CursorListener> null_cursor_listener{};
352- droidinput::sp<droidinput::EventHubInterface> event_hub(new droidinput::EventHub());
353+ auto config = std::make_shared<mia::DefaultInputConfiguration>(event_filters, view_area, null_cursor_listener);
354
355- return std::make_shared<mia::InputManager>(
356- event_hub,
357- event_filters,
358- view_area,
359- null_cursor_listener);
360+ return std::make_shared<mia::InputManager>(config);
361 }
362
363=== modified file 'src/input/android/android_input_manager.h'
364--- src/input/android/android_input_manager.h 2013-03-04 16:02:02 +0000
365+++ src/input/android/android_input_manager.h 2013-03-06 17:03:21 +0000
366@@ -21,7 +21,6 @@
367 #define MIR_INPUT_ANDROID_INPUT_MANAGER_H_
368
369 #include "mir/input/input_manager.h"
370-#include "../event_filter_chain.h"
371
372 #include <utils/StrongPointer.h>
373
374@@ -30,10 +29,7 @@
375 namespace android
376 {
377 class EventHubInterface;
378-class InputDispatcher;
379-class InputDispatcherThread;
380-class InputReader;
381-class InputReaderThread;
382+class InputDispatcherInterface;
383 }
384
385 namespace droidinput = android;
386@@ -46,20 +42,18 @@
387 }
388 namespace input
389 {
390-
391 class CursorListener;
392
393 namespace android
394 {
395+class InputThread;
396+class InputConfiguration;
397
398 class InputManager : public mir::input::InputManager
399 {
400 public:
401 explicit InputManager(
402- const droidinput::sp<droidinput::EventHubInterface>& event_hub,
403- const std::initializer_list<std::shared_ptr<input::EventFilter> const>& filters,
404- std::shared_ptr<graphics::ViewableArea> const& view_area,
405- std::shared_ptr<CursorListener> const& cursor_listener);
406+ std::shared_ptr<InputConfiguration> const& input_configuration);
407 virtual ~InputManager();
408
409 virtual void start();
410@@ -71,14 +65,10 @@
411
412 private:
413 droidinput::sp<droidinput::EventHubInterface> event_hub;
414- std::shared_ptr<EventFilterChain> filter_chain;
415- droidinput::sp<droidinput::InputDispatcher> dispatcher;
416- droidinput::sp<droidinput::InputReader> reader;
417+ droidinput::sp<droidinput::InputDispatcherInterface> dispatcher;
418
419- // It's important to keep droidinput::sp to dispatcher_thread
420- // and reader_thread or they will free themselves on exit.
421- droidinput::sp<droidinput::InputReaderThread> reader_thread;
422- droidinput::sp<droidinput::InputDispatcherThread> dispatcher_thread;
423+ std::shared_ptr<InputThread> reader_thread;
424+ std::shared_ptr<InputThread> dispatcher_thread;
425 };
426
427 }
428
429=== added file 'src/input/android/android_input_thread.h'
430--- src/input/android/android_input_thread.h 1970-01-01 00:00:00 +0000
431+++ src/input/android/android_input_thread.h 2013-03-06 17:03:21 +0000
432@@ -0,0 +1,47 @@
433+/*
434+ * Copyright © 2013 Canonical Ltd.
435+ *
436+ * This program is free software: you can redistribute it and/or modify it
437+ * under the terms of the GNU Lesser General Public License version 3,
438+ * as published by the Free Software Foundation.
439+ *
440+ * This program is distributed in the hope that it will be useful,
441+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
442+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
443+ * GNU General Public License for more details.
444+ *
445+ * You should have received a copy of the GNU Lesser General Public License
446+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
447+ *
448+ * Authored by: Robert Carr <robert.carr@canonical.com>
449+ */
450+
451+#ifndef MIR_INPUT_ANDROID_INPUT_THREAD_H_
452+#define MIR_INPUT_ANDROID_INPUT_THREAD_H_
453+
454+namespace mir
455+{
456+namespace input
457+{
458+namespace android
459+{
460+class InputThread
461+{
462+public:
463+ virtual ~InputThread() {}
464+
465+ virtual void start() = 0;
466+ virtual void request_stop() = 0;
467+ virtual void join() = 0;
468+
469+protected:
470+ InputThread() {};
471+ InputThread(const InputThread&) = delete;
472+ InputThread& operator=(const InputThread&) = delete;
473+};
474+
475+}
476+}
477+} // namespace mir
478+
479+#endif // MIR_INPUT_ANDROID_INPUT_THREAD_H_
480
481=== added file 'src/input/android/default_android_input_configuration.cpp'
482--- src/input/android/default_android_input_configuration.cpp 1970-01-01 00:00:00 +0000
483+++ src/input/android/default_android_input_configuration.cpp 2013-03-06 17:03:21 +0000
484@@ -0,0 +1,149 @@
485+/*
486+ * Copyright © 2013 Canonical Ltd.
487+ *
488+ * This program is free software: you can redistribute it and/or modify it
489+ * under the terms of the GNU Lesser General Public License version 3,
490+ * as published by the Free Software Foundation.
491+ *
492+ * This program is distributed in the hope that it will be useful,
493+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
494+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
495+ * GNU General Public License for more details.
496+ *
497+ * You should have received a copy of the GNU Lesser General Public License
498+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
499+ *
500+ * Authored by: Robert Carr <robert.carr@canonical.com>
501+ */
502+
503+#include "default_android_input_configuration.h"
504+#include "event_filter_dispatcher_policy.h"
505+#include "android_input_reader_policy.h"
506+#include "android_input_thread.h"
507+#include "../event_filter_chain.h"
508+
509+#include <EventHub.h>
510+#include <InputDispatcher.h>
511+#include <InputReader.h>
512+
513+namespace droidinput = android;
514+
515+namespace mi = mir::input;
516+namespace mia = mi::android;
517+namespace mg = mir::graphics;
518+
519+namespace
520+{
521+class CommonInputThread : public mia::InputThread
522+{
523+public:
524+ CommonInputThread(std::string const& name, droidinput::sp<droidinput::Thread> const& thread)
525+ : name(name),
526+ thread(thread)
527+ {
528+ }
529+ virtual ~CommonInputThread()
530+ {
531+ }
532+
533+ void start()
534+ {
535+ thread->run(name.c_str(), droidinput::PRIORITY_URGENT_DISPLAY);
536+ }
537+ void request_stop()
538+ {
539+ thread->requestExit();
540+ }
541+ void join()
542+ {
543+ thread->join();
544+ }
545+
546+protected:
547+ CommonInputThread(const CommonInputThread&) = delete;
548+ CommonInputThread& operator=(const CommonInputThread&) = delete;
549+
550+private:
551+ std::string const name;
552+ droidinput::sp<droidinput::Thread> const thread;
553+};
554+}
555+
556+mia::DefaultInputConfiguration::DefaultInputConfiguration(std::initializer_list<std::shared_ptr<mi::EventFilter> const> const& filters,
557+ std::shared_ptr<mg::ViewableArea> const& view_area,
558+ std::shared_ptr<mi::CursorListener> const& cursor_listener)
559+ : filter_chain(std::make_shared<mi::EventFilterChain>(filters)),
560+ view_area(view_area),
561+ cursor_listener(cursor_listener)
562+{
563+}
564+
565+mia::DefaultInputConfiguration::~DefaultInputConfiguration()
566+{
567+}
568+
569+droidinput::sp<droidinput::EventHubInterface> mia::DefaultInputConfiguration::the_event_hub()
570+{
571+ return event_hub(
572+ [this]()
573+ {
574+ return new droidinput::EventHub();
575+ });
576+}
577+
578+droidinput::sp<droidinput::InputDispatcherPolicyInterface> mia::DefaultInputConfiguration::the_dispatcher_policy()
579+{
580+ return dispatcher_policy(
581+ [this]()
582+ {
583+ return new mia::EventFilterDispatcherPolicy(filter_chain);
584+ });
585+}
586+
587+droidinput::sp<droidinput::InputDispatcherInterface> mia::DefaultInputConfiguration::the_dispatcher()
588+{
589+ return dispatcher(
590+ [this]()
591+ {
592+ return new droidinput::InputDispatcher(the_dispatcher_policy());
593+ });
594+}
595+
596+droidinput::sp<droidinput::InputReaderPolicyInterface> mia::DefaultInputConfiguration::the_reader_policy()
597+{
598+ return reader_policy(
599+ [this]()
600+ {
601+ return new mia::InputReaderPolicy(view_area, cursor_listener);
602+ });
603+}
604+
605+
606+droidinput::sp<droidinput::InputReaderInterface> mia::DefaultInputConfiguration::the_reader()
607+{
608+ return reader(
609+ [this]()
610+ {
611+ return new droidinput::InputReader(the_event_hub(), the_reader_policy(), the_dispatcher());
612+ });
613+}
614+
615+std::shared_ptr<mia::InputThread> mia::DefaultInputConfiguration::the_dispatcher_thread()
616+{
617+ return dispatcher_thread(
618+ [this]()
619+ {
620+ return std::make_shared<CommonInputThread>("InputDispatcher",
621+ new droidinput::InputDispatcherThread(the_dispatcher()));
622+ });
623+}
624+
625+std::shared_ptr<mia::InputThread> mia::DefaultInputConfiguration::the_reader_thread()
626+{
627+ return reader_thread(
628+ [this]()
629+ {
630+ return std::make_shared<CommonInputThread>("InputReader",
631+ new droidinput::InputReaderThread(the_reader()));
632+ });
633+}
634
635=== added file 'src/input/android/default_android_input_configuration.h'
636--- src/input/android/default_android_input_configuration.h 1970-01-01 00:00:00 +0000
637+++ src/input/android/default_android_input_configuration.h 2013-03-06 17:03:21 +0000
638@@ -0,0 +1,117 @@
639+/*
640+ * Copyright © 2013 Canonical Ltd.
641+ *
642+ * This program is free software: you can redistribute it and/or modify it
643+ * under the terms of the GNU Lesser General Public License version 3,
644+ * as published by the Free Software Foundation.
645+ *
646+ * This program is distributed in the hope that it will be useful,
647+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
648+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
649+ * GNU General Public License for more details.
650+ *
651+ * You should have received a copy of the GNU Lesser General Public License
652+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
653+ *
654+ * Authored by: Robert Carr <robert.carr@canonical.com>
655+ */
656+
657+#ifndef MIR_INPUT_ANDROID_DEFAULT_ANDROID_INPUT_CONFIGURATION_H_
658+#define MIR_INPUT_ANDROID_DEFAULT_ANDROID_INPUT_CONFIGURATION_H_
659+
660+#include "android_input_configuration.h"
661+
662+#include "mir/cached_ptr.h"
663+
664+#include <utils/RefBase.h>
665+#include <utils/StrongPointer.h>
666+
667+#include <functional>
668+
669+namespace droidinput = android;
670+
671+namespace android
672+{
673+class InputReaderInterface;
674+class InputReaderPolicyInterface;
675+class InputDispatcherPolicyInterface;
676+}
677+
678+namespace mir
679+{
680+namespace graphics
681+{
682+class ViewableArea;
683+}
684+namespace input
685+{
686+class EventFilter;
687+class EventFilterChain;
688+class CursorListener;
689+
690+namespace android
691+{
692+
693+class DefaultInputConfiguration : public InputConfiguration
694+{
695+public:
696+ DefaultInputConfiguration(std::initializer_list<std::shared_ptr<EventFilter> const> const& filters,
697+ std::shared_ptr<graphics::ViewableArea> const& view_area,
698+ std::shared_ptr<CursorListener> const& cursor_listener);
699+ virtual ~DefaultInputConfiguration();
700+
701+ droidinput::sp<droidinput::EventHubInterface> the_event_hub();
702+ droidinput::sp<droidinput::InputDispatcherInterface> the_dispatcher();
703+ droidinput::sp<droidinput::InputReaderInterface> the_reader();
704+
705+ std::shared_ptr<InputThread> the_dispatcher_thread();
706+ std::shared_ptr<InputThread> the_reader_thread();
707+
708+ virtual droidinput::sp<droidinput::InputDispatcherPolicyInterface> the_dispatcher_policy();
709+ virtual droidinput::sp<droidinput::InputReaderPolicyInterface> the_reader_policy();
710+
711+protected:
712+ DefaultInputConfiguration(DefaultInputConfiguration const&) = delete;
713+ DefaultInputConfiguration& operator=(DefaultInputConfiguration const&) = delete;
714+
715+private:
716+ template <typename Type>
717+ class CachedAndroidPtr
718+ {
719+ droidinput::wp<Type> cache;
720+
721+ CachedAndroidPtr(CachedAndroidPtr const&) = delete;
722+ CachedAndroidPtr& operator=(CachedAndroidPtr const&) = delete;
723+
724+ public:
725+ CachedAndroidPtr() = default;
726+
727+ droidinput::sp<Type> operator()(std::function<droidinput::sp<Type>()> make)
728+ {
729+ auto result = cache.promote();
730+ if (!result.get())
731+ {
732+ cache = result = make();
733+ }
734+ return result;
735+ }
736+ };
737+
738+ std::shared_ptr<EventFilterChain> const filter_chain;
739+ std::shared_ptr<graphics::ViewableArea> const view_area;
740+ std::shared_ptr<CursorListener> const cursor_listener;
741+
742+ CachedPtr<InputThread> dispatcher_thread;
743+ CachedPtr<InputThread> reader_thread;
744+ CachedAndroidPtr<droidinput::EventHubInterface> event_hub;
745+ CachedAndroidPtr<droidinput::InputDispatcherPolicyInterface> dispatcher_policy;
746+ CachedAndroidPtr<droidinput::InputReaderPolicyInterface> reader_policy;
747+ CachedAndroidPtr<droidinput::InputDispatcherInterface> dispatcher;
748+ CachedAndroidPtr<droidinput::InputReaderInterface> reader;
749+};
750+
751+}
752+}
753+} // namespace mir
754+
755+#endif // MIR_INPUT_ANDROID_DEFAULT_ANDROID_INPUT_CONFIGURATION_H_
756
757=== modified file 'tests/integration-tests/input/android/test_android_cursor_listener.cpp'
758--- tests/integration-tests/input/android/test_android_cursor_listener.cpp 2013-02-21 17:39:09 +0000
759+++ tests/integration-tests/input/android/test_android_cursor_listener.cpp 2013-03-06 17:03:21 +0000
760@@ -19,10 +19,12 @@
761
762 #include "mir/input/event_filter.h"
763 #include "src/input/android/android_input_manager.h"
764+#include "src/input/android/default_android_input_configuration.h"
765 #include "mir/input/cursor_listener.h"
766
767 #include "mir_test/fake_shared.h"
768 #include "mir_test/fake_event_hub.h"
769+#include "mir_test/fake_event_hub_input_configuration.h"
770 #include "mir_test_doubles/mock_event_filter.h"
771 #include "mir_test/wait_condition.h"
772 #include "mir_test/event_factory.h"
773@@ -57,22 +59,24 @@
774 {
775 void SetUp()
776 {
777- event_hub = new mia::FakeEventHub();
778-
779 static const geom::Rectangle visible_rectangle
780 {
781 geom::Point(),
782 geom::Size{geom::Width(1024), geom::Height(1024)}
783 };
784
785+ configuration = std::make_shared<mtd::FakeEventHubInputConfiguration>(
786+ std::initializer_list<std::shared_ptr<mi::EventFilter> const>{mt::fake_shared(event_filter)},
787+ mt::fake_shared(viewable_area),
788+ mt::fake_shared(cursor_listener));
789+
790 ON_CALL(viewable_area, view_area())
791 .WillByDefault(Return(visible_rectangle));
792
793- input_manager.reset(new mia::InputManager(
794- event_hub,
795- {mt::fake_shared(event_filter)},
796- mt::fake_shared(viewable_area),
797- mt::fake_shared(cursor_listener)));
798+ fake_event_hub = configuration->the_fake_event_hub();
799+
800+ input_manager = std::make_shared<mia::InputManager>(configuration);
801+
802 input_manager->start();
803 }
804
805@@ -81,7 +85,8 @@
806 input_manager->stop();
807 }
808
809- android::sp<mia::FakeEventHub> event_hub;
810+ std::shared_ptr<mtd::FakeEventHubInputConfiguration> configuration;
811+ mia::FakeEventHub* fake_event_hub;
812 MockEventFilter event_filter;
813 NiceMock<mtd::MockViewableArea> viewable_area;
814 std::shared_ptr<mia::InputManager> input_manager;
815@@ -106,10 +111,10 @@
816 EXPECT_CALL(event_filter, handles(_))
817 .WillOnce(ReturnFalseAndWakeUp(wait_condition));
818
819- event_hub->synthesize_builtin_cursor_added();
820- event_hub->synthesize_device_scan_complete();
821+ fake_event_hub->synthesize_builtin_cursor_added();
822+ fake_event_hub->synthesize_device_scan_complete();
823
824- event_hub->synthesize_event(mis::a_motion_event().with_movement(x, y));
825+ fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(x, y));
826
827 wait_condition->wait_for_at_most_seconds(1);
828 }
829
830=== modified file 'tests/integration-tests/input/android/test_android_input_manager.cpp'
831--- tests/integration-tests/input/android/test_android_input_manager.cpp 2013-02-05 18:12:46 +0000
832+++ tests/integration-tests/input/android/test_android_input_manager.cpp 2013-03-06 17:03:21 +0000
833@@ -18,15 +18,19 @@
834 */
835
836 #include "mir/input/event_filter.h"
837+#include "src/input/android/default_android_input_configuration.h"
838 #include "src/input/android/android_input_manager.h"
839
840 #include "mir_test/fake_shared.h"
841 #include "mir_test/fake_event_hub.h"
842+#include "mir_test/fake_event_hub_input_configuration.h"
843 #include "mir_test_doubles/mock_event_filter.h"
844 #include "mir_test_doubles/mock_viewable_area.h"
845 #include "mir_test/wait_condition.h"
846 #include "mir_test/event_factory.h"
847
848+#include <EventHub.h>
849+
850 #include <gmock/gmock.h>
851 #include <gtest/gtest.h>
852
853@@ -54,18 +58,15 @@
854 class AndroidInputManagerAndEventFilterDispatcherSetup : public testing::Test
855 {
856 public:
857- void SetUp()
858+ AndroidInputManagerAndEventFilterDispatcherSetup()
859 {
860+ configuration = std::make_shared<mtd::FakeEventHubInputConfiguration>(std::initializer_list<std::shared_ptr<mi::EventFilter> const>{mt::fake_shared(event_filter)}, mt::fake_shared(viewable_area), null_cursor_listener);
861 ON_CALL(viewable_area, view_area())
862 .WillByDefault(Return(default_view_area));
863+
864+ fake_event_hub = configuration->the_fake_event_hub();
865
866- event_hub = new mia::FakeEventHub();
867- input_manager.reset(
868- new mia::InputManager(
869- event_hub,
870- {mt::fake_shared(event_filter)},
871- mt::fake_shared(viewable_area),
872- null_cursor_listener));
873+ input_manager = std::make_shared<mia::InputManager>(configuration);
874
875 input_manager->start();
876 }
877@@ -76,7 +77,8 @@
878 }
879
880 protected:
881- android::sp<mia::FakeEventHub> event_hub;
882+ std::shared_ptr<mtd::FakeEventHubInputConfiguration> configuration;
883+ mia::FakeEventHub* fake_event_hub;
884 std::shared_ptr<mia::InputManager> input_manager;
885 MockEventFilter event_filter;
886 NiceMock<mtd::MockViewableArea> viewable_area;
887@@ -96,10 +98,10 @@
888 .Times(1)
889 .WillOnce(ReturnFalseAndWakeUp(&wait_condition));
890
891- event_hub->synthesize_builtin_keyboard_added();
892- event_hub->synthesize_device_scan_complete();
893+ fake_event_hub->synthesize_builtin_keyboard_added();
894+ fake_event_hub->synthesize_device_scan_complete();
895
896- event_hub->synthesize_event(mis::a_key_down_event()
897+ fake_event_hub->synthesize_event(mis::a_key_down_event()
898 .of_scancode(KEY_ENTER));
899
900 wait_condition.wait_for_at_most_seconds(1);
901@@ -117,10 +119,10 @@
902 .Times(1)
903 .WillOnce(ReturnFalseAndWakeUp(&wait_condition));
904
905- event_hub->synthesize_builtin_cursor_added();
906- event_hub->synthesize_device_scan_complete();
907+ fake_event_hub->synthesize_builtin_cursor_added();
908+ fake_event_hub->synthesize_device_scan_complete();
909
910- event_hub->synthesize_event(mis::a_button_down_event().of_button(BTN_LEFT));
911+ fake_event_hub->synthesize_event(mis::a_button_down_event().of_button(BTN_LEFT));
912
913 wait_condition.wait_for_at_most_seconds(1);
914 }
915@@ -143,11 +145,11 @@
916 .WillOnce(ReturnFalseAndWakeUp(&wait_condition));
917 }
918
919- event_hub->synthesize_builtin_cursor_added();
920- event_hub->synthesize_device_scan_complete();
921+ fake_event_hub->synthesize_builtin_cursor_added();
922+ fake_event_hub->synthesize_device_scan_complete();
923
924- event_hub->synthesize_event(mis::a_motion_event().with_movement(100,100));
925- event_hub->synthesize_event(mis::a_motion_event().with_movement(100,0));
926+ fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(100,100));
927+ fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(100,0));
928
929 wait_condition.wait_for_at_most_seconds(1);
930 }
931
932=== modified file 'tests/mir_test_doubles/CMakeLists.txt'
933--- tests/mir_test_doubles/CMakeLists.txt 2013-03-04 15:54:45 +0000
934+++ tests/mir_test_doubles/CMakeLists.txt 2013-03-06 17:03:21 +0000
935@@ -13,6 +13,7 @@
936 if (NOT MIR_DISABLE_INPUT)
937 list(APPEND TEST_UTILS_SRCS
938 fake_event_hub.cpp
939+ fake_event_hub_input_configuration.cpp
940 )
941 endif()
942
943
944=== added file 'tests/mir_test_doubles/fake_event_hub_input_configuration.cpp'
945--- tests/mir_test_doubles/fake_event_hub_input_configuration.cpp 1970-01-01 00:00:00 +0000
946+++ tests/mir_test_doubles/fake_event_hub_input_configuration.cpp 2013-03-06 17:03:21 +0000
947@@ -0,0 +1,48 @@
948+/*
949+ * Copyright © 2013 Canonical Ltd.
950+ *
951+ * This program is free software: you can redistribute it and/or modify it
952+ * under the terms of the GNU Lesser General Public License version 3,
953+ * as published by the Free Software Foundation.
954+ *
955+ * This program is distributed in the hope that it will be useful,
956+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
957+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
958+ * GNU General Public License for more details.
959+ *
960+ * You should have received a copy of the GNU Lesser General Public License
961+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
962+ *
963+ * Authored by: Robert Carr <robert.carr@canonical.com>
964+ */
965+
966+#include "mir_test/fake_event_hub_input_configuration.h"
967+#include "mir_test/fake_event_hub.h"
968+
969+namespace mi = mir::input;
970+namespace mia = mi::android;
971+namespace mg = mir::graphics;
972+namespace mtd = mir::test::doubles;
973+
974+mtd::FakeEventHubInputConfiguration::FakeEventHubInputConfiguration(
975+ std::initializer_list<std::shared_ptr<mir::input::EventFilter> const> const& filters,
976+ std::shared_ptr<mir::graphics::ViewableArea> const& view_area,
977+ std::shared_ptr<mir::input::CursorListener> const& cursor_listener)
978+ : DefaultInputConfiguration(filters, view_area, cursor_listener)
979+{
980+ event_hub = new mia::FakeEventHub();
981+}
982+
983+mtd::FakeEventHubInputConfiguration::~FakeEventHubInputConfiguration()
984+{
985+}
986+
987+droidinput::sp<droidinput::EventHubInterface> mtd::FakeEventHubInputConfiguration::the_event_hub()
988+{
989+ return event_hub;
990+}
991+
992+mia::FakeEventHub* mtd::FakeEventHubInputConfiguration::the_fake_event_hub()
993+{
994+ return event_hub.get();
995+}
996
997=== modified file 'tests/unit-tests/input/android/CMakeLists.txt'
998--- tests/unit-tests/input/android/CMakeLists.txt 2013-03-04 15:54:45 +0000
999+++ tests/unit-tests/input/android/CMakeLists.txt 2013-03-06 17:03:21 +0000
1000@@ -4,6 +4,7 @@
1001 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_pointer_controller.cpp
1002 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_lexicon.cpp
1003 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_reader_policy.cpp
1004+ ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_manager.cpp
1005 )
1006
1007 set(
1008
1009=== added file 'tests/unit-tests/input/android/test_android_input_manager.cpp'
1010--- tests/unit-tests/input/android/test_android_input_manager.cpp 1970-01-01 00:00:00 +0000
1011+++ tests/unit-tests/input/android/test_android_input_manager.cpp 2013-03-06 17:03:21 +0000
1012@@ -0,0 +1,198 @@
1013+/*
1014+ * Copyright © 2013 Canonical Ltd.
1015+ *
1016+ * This program is free software: you can redistribute it and/or modify it
1017+ * under the terms of the GNU Lesser General Public License version 3,
1018+ * as published by the Free Software Foundation.
1019+ *
1020+ * This program is distributed in the hope that it will be useful,
1021+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1022+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1023+ * GNU General Public License for more details.
1024+ *
1025+ * You should have received a copy of the GNU Lesser General Public License
1026+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1027+ *
1028+ * Authored by: Robert Carr <robert.carr@canonical.com>
1029+ */
1030+
1031+#include "src/input/android/android_input_manager.h"
1032+#include "src/input/android/android_input_configuration.h"
1033+#include "src/input/android/android_input_thread.h"
1034+#include "src/input/android/android_input_constants.h"
1035+
1036+#include "mir_test_doubles/mock_viewable_area.h"
1037+#include "mir_test/fake_shared.h"
1038+
1039+#include <InputDispatcher.h>
1040+#include <InputListener.h>
1041+#include <EventHub.h>
1042+#include <utils/StrongPointer.h>
1043+
1044+#include <gtest/gtest.h>
1045+#include <gmock/gmock.h>
1046+
1047+#include <initializer_list>
1048+
1049+namespace droidinput = android;
1050+
1051+namespace mi = mir::input;
1052+namespace mia = mir::input::android;
1053+namespace mg = mir::graphics;
1054+namespace geom = mir::geometry;
1055+namespace mt = mir::test;
1056+namespace mtd = mt::doubles;
1057+
1058+// Mock objects
1059+namespace
1060+{
1061+
1062+struct MockInputConfiguration : public mia::InputConfiguration
1063+{
1064+ MOCK_METHOD0(the_event_hub, droidinput::sp<droidinput::EventHubInterface>());
1065+ MOCK_METHOD0(the_dispatcher, droidinput::sp<droidinput::InputDispatcherInterface>());
1066+ MOCK_METHOD0(the_dispatcher_thread, std::shared_ptr<mia::InputThread>());
1067+ MOCK_METHOD0(the_reader_thread, std::shared_ptr<mia::InputThread>());
1068+};
1069+
1070+struct MockInputDispatcher : public droidinput::InputDispatcherInterface
1071+{
1072+ // droidinput::InputDispatcher interface
1073+ MOCK_METHOD1(dump, void(droidinput::String8&));
1074+ MOCK_METHOD0(monitor, void());
1075+ MOCK_METHOD0(dispatchOnce, void());
1076+ MOCK_METHOD6(injectInputEvent, int32_t(droidinput::InputEvent const*, int32_t, int32_t, int32_t, int32_t, uint32_t));
1077+ MOCK_METHOD1(setInputWindows, void(droidinput::Vector<droidinput::sp<droidinput::InputWindowHandle>> const&));
1078+ MOCK_METHOD1(setFocusedApplication, void(droidinput::sp<droidinput::InputApplicationHandle> const&));
1079+ MOCK_METHOD2(setInputDispatchMode, void(bool, bool));
1080+ MOCK_METHOD1(setInputFilterEnabled, void(bool));
1081+ MOCK_METHOD2(transferTouchFocus, bool(droidinput::sp<droidinput::InputChannel> const&, droidinput::sp<droidinput::InputChannel> const&));
1082+ MOCK_METHOD3(registerInputChannel, droidinput::status_t(droidinput::sp<droidinput::InputChannel> const&, droidinput::sp<droidinput::InputWindowHandle> const&, bool));
1083+ MOCK_METHOD1(unregisterInputChannel, droidinput::status_t(droidinput::sp<droidinput::InputChannel> const&));
1084+
1085+ // droidinput::InputListener interface
1086+ MOCK_METHOD1(notifyConfigurationChanged, void(droidinput::NotifyConfigurationChangedArgs const*));
1087+ MOCK_METHOD1(notifyKey, void(droidinput::NotifyKeyArgs const*));
1088+ MOCK_METHOD1(notifyMotion, void(droidinput::NotifyMotionArgs const*));
1089+ MOCK_METHOD1(notifySwitch, void(droidinput::NotifySwitchArgs const*));
1090+ MOCK_METHOD1(notifyDeviceReset, void(droidinput::NotifyDeviceResetArgs const*));
1091+};
1092+
1093+struct MockEventHub : public droidinput::EventHubInterface
1094+{
1095+ MOCK_CONST_METHOD1(getDeviceClasses, uint32_t(int32_t));
1096+ MOCK_CONST_METHOD1(getDeviceIdentifier, droidinput::InputDeviceIdentifier(int32_t));
1097+ MOCK_CONST_METHOD2(getConfiguration, void(int32_t, droidinput::PropertyMap*));
1098+ MOCK_CONST_METHOD3(getAbsoluteAxisInfo, droidinput::status_t(int32_t, int, droidinput::RawAbsoluteAxisInfo*));
1099+ MOCK_CONST_METHOD2(hasRelativeAxis, bool(int32_t, int));
1100+ MOCK_CONST_METHOD2(hasInputProperty, bool(int32_t, int));
1101+ MOCK_CONST_METHOD5(mapKey, droidinput::status_t(int32_t, int32_t, int32_t, int32_t*, uint32_t*));
1102+ MOCK_CONST_METHOD3(mapAxis, droidinput::status_t(int32_t, int32_t, droidinput::AxisInfo*));
1103+ MOCK_METHOD1(setExcludedDevices, void(droidinput::Vector<droidinput::String8> const&));
1104+ MOCK_METHOD3(getEvents, size_t(int, droidinput::RawEvent*, size_t));
1105+ MOCK_CONST_METHOD2(getScanCodeState, int32_t(int32_t, int32_t));
1106+ MOCK_CONST_METHOD2(getKeyCodeState, int32_t(int32_t, int32_t));
1107+ MOCK_CONST_METHOD2(getSwitchState, int32_t(int32_t, int32_t));
1108+ MOCK_CONST_METHOD3(getAbsoluteAxisValue, droidinput::status_t(int32_t, int32_t, int32_t*));
1109+ MOCK_CONST_METHOD4(markSupportedKeyCodes, bool(int32_t, size_t, int32_t const*, uint8_t*));
1110+ MOCK_CONST_METHOD2(hasScanCode, bool(int32_t, int32_t));
1111+ MOCK_CONST_METHOD2(hasLed, bool(int32_t, int32_t));
1112+ MOCK_METHOD3(setLedState, void(int32_t, int32_t, bool));
1113+ MOCK_CONST_METHOD2(getVirtualKeyDefinitions, void(int32_t, droidinput::Vector<droidinput::VirtualKeyDefinition>&));
1114+ MOCK_CONST_METHOD1(getKeyCharacterMap, droidinput::sp<droidinput::KeyCharacterMap>(int32_t));
1115+ MOCK_METHOD2(setKeyboardLayoutOverlay, bool(int32_t, const droidinput::sp<droidinput::KeyCharacterMap>&));
1116+ MOCK_METHOD2(vibrate, void(int32_t, nsecs_t));
1117+ MOCK_METHOD1(cancelVibrate, void(int32_t));
1118+ MOCK_METHOD0(requestReopenDevices, void());
1119+ MOCK_METHOD0(wake, void());
1120+ MOCK_METHOD1(dump, void(droidinput::String8&));
1121+ MOCK_METHOD0(monitor, void());
1122+};
1123+
1124+struct MockInputThread : public mia::InputThread
1125+{
1126+ MOCK_METHOD0(start, void());
1127+ MOCK_METHOD0(request_stop, void());
1128+ MOCK_METHOD0(join, void());
1129+};
1130+
1131+}
1132+
1133+// Test fixture
1134+namespace
1135+{
1136+
1137+struct AndroidInputManagerSetup : public testing::Test
1138+{
1139+ void SetUp()
1140+ {
1141+ using namespace ::testing;
1142+
1143+ const geom::Rectangle default_view_area =
1144+ geom::Rectangle{geom::Point(),
1145+ geom::Size{geom::Width(1600), geom::Height(1400)}};
1146+
1147+
1148+ ON_CALL(view_area, view_area())
1149+ .WillByDefault(Return(default_view_area));
1150+
1151+ event_hub = new MockEventHub();
1152+ dispatcher = new MockInputDispatcher();
1153+ dispatcher_thread = std::make_shared<MockInputThread>();
1154+ reader_thread = std::make_shared<MockInputThread>();
1155+
1156+ ON_CALL(config, the_event_hub()).WillByDefault(Return(event_hub));
1157+ ON_CALL(config, the_dispatcher()).WillByDefault(Return(dispatcher));
1158+ ON_CALL(config, the_reader_thread()).WillByDefault(Return(reader_thread));
1159+ ON_CALL(config, the_dispatcher_thread()).WillByDefault(Return(dispatcher_thread));
1160+ }
1161+ mtd::MockViewableArea view_area;
1162+
1163+ testing::NiceMock<MockInputConfiguration> config;
1164+ droidinput::sp<MockEventHub> event_hub;
1165+ droidinput::sp<MockInputDispatcher> dispatcher;
1166+ std::shared_ptr<MockInputThread> dispatcher_thread;
1167+ std::shared_ptr<MockInputThread> reader_thread;
1168+};
1169+
1170+}
1171+
1172+TEST_F(AndroidInputManagerSetup, takes_input_setup_from_configuration)
1173+{
1174+ using namespace ::testing;
1175+
1176+ EXPECT_CALL(config, the_event_hub()).Times(1);
1177+ EXPECT_CALL(config, the_dispatcher()).Times(1);
1178+ EXPECT_CALL(config, the_reader_thread()).Times(1);
1179+ EXPECT_CALL(config, the_dispatcher_thread()).Times(1);
1180+
1181+ mia::InputManager manager(mt::fake_shared(config));
1182+
1183+}
1184+
1185+TEST_F(AndroidInputManagerSetup, start_and_stop)
1186+{
1187+ using namespace ::testing;
1188+
1189+ EXPECT_CALL(*dispatcher, setInputDispatchMode(mia::DispatchEnabled, mia::DispatchUnfrozen)).Times(1);
1190+ EXPECT_CALL(*dispatcher, setInputFilterEnabled(true)).Times(1);
1191+
1192+ EXPECT_CALL(*reader_thread, start()).Times(1);
1193+ EXPECT_CALL(*dispatcher_thread, start()).Times(1);
1194+
1195+ {
1196+ InSequence seq;
1197+
1198+ EXPECT_CALL(*dispatcher_thread, request_stop());
1199+ EXPECT_CALL(*dispatcher, setInputDispatchMode(mia::DispatchDisabled, mia::DispatchFrozen)).Times(1);
1200+ EXPECT_CALL(*dispatcher_thread, join());
1201+ EXPECT_CALL(*reader_thread, request_stop());
1202+ EXPECT_CALL(*event_hub, wake());
1203+ EXPECT_CALL(*reader_thread, join());
1204+ }
1205+
1206+ mia::InputManager manager(mt::fake_shared(config));
1207+
1208+ manager.start();
1209+ manager.stop();
1210+}

Subscribers

People subscribed via source and target branches