Merge lp:~robertcarr/mir/improve-input-manager-testing into lp:~mir-team/mir/trunk
- improve-input-manager-testing
- Merge into trunk
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 |
Related bugs: |
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::InputConfi
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-
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).
PS Jenkins bot (ps-jenkins) wrote : | # |
Alexandros Frantzis (afrantzis) wrote : | # |
827 + fake_event_hub = dynamic_
890 + fake_event_hub = dynamic_
It would be cleaner to have a mia::FakeEventHub& FakeEventHubInp
376 std::shared_
Would it make sense for mi::create_
1057 +#include "mir/input/
1084 +static const std::shared_
1085 +static std::initialize
Are these used somewhere?
1086 +static const geom::Rectangle default_view_area =
Is this useful outside the test fixture construction?
Robert Carr (robertcarr) wrote : | # |
>> It would be cleaner to have a mia::FakeEventHub& FakeEventHubInp
>> 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_
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/
>> 1084 +static const std::shared_
>> 1085 +static std::initialize
Gone!
>> 1086 +static const geom::Rectangle default_view_area =
Moved!
Alan Griffiths (alan-griffiths) wrote : | # |
123 + mir::CachedPtr<
...
Adding "mir::" is pointless noise.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:486
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild:
http://
Robert Carr (robertcarr) wrote : | # |
>> Adding "mir::" is pointless noise.
Removed
Alan Griffiths (alan-griffiths) wrote : | # |
include/
copyright header should be LGPL
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:487
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild:
http://
Robert Carr (robertcarr) wrote : | # |
Fixed copyright headers
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:488
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:489
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : | # |
Looks good.
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
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 | +} |
PASSED: Continuous integration, rev:483 jenkins. qa.ubuntu. com/job/ mir-ci/ 1145/ jenkins. qa.ubuntu. com/job/ mir-ci/ ./build= pbuilder, distribution= quantal, flavor= amd64/1145/ console
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild: jenkins. qa.ubuntu. com/job/ mir-ci/ 1145//rebuild/?
http://