Status: | Merged |
---|---|
Approved by: | Andreas Pokorny |
Approved revision: | 3333 |
Merged at revision: | 1267 |
Proposed branch: | lp:mir/0.20 |
Merge into: | lp:mir/ubuntu |
Diff against target: |
455 lines (+231/-54) 8 files modified
CMakeLists.txt (+1/-1) debian/changelog (+11/-0) include/test/mir/test/doubles/mock_input_device_hub.h (+43/-0) src/server/input/default_configuration.cpp (+37/-24) src/server/input/default_input_device_hub.cpp (+14/-8) src/server/input/key_repeat_dispatcher.cpp (+41/-0) src/server/input/key_repeat_dispatcher.h (+7/-4) tests/unit-tests/input/test_key_repeat_dispatcher.cpp (+77/-17) |
To merge this branch: | bzr merge lp:mir/0.20 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Mir CI Bot | continuous-integration | Needs Fixing | |
Mir development team | Pending | ||
Review via email: mp+288248@code.launchpad.net |
Commit message
Bug fix release 0.20.2
Description of the change
mir release 0.20.2
Mir CI Bot (mir-ci-bot) wrote : | # |
Andreas Pokorny (andreas-pokorny) wrote : | # |
https:/
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3332
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3332
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3332
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 3333. By Andreas Pokorny
-
bump library version
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3330
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3333
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3333
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2016-02-24 13:35:43 +0000 |
3 | +++ CMakeLists.txt 2016-03-07 15:15:54 +0000 |
4 | @@ -29,7 +29,7 @@ |
5 | |
6 | set(MIR_VERSION_MAJOR 0) |
7 | set(MIR_VERSION_MINOR 20) |
8 | -set(MIR_VERSION_PATCH 1) |
9 | +set(MIR_VERSION_PATCH 2) |
10 | |
11 | add_definitions(-DMIR_VERSION_MAJOR=${MIR_VERSION_MAJOR}) |
12 | add_definitions(-DMIR_VERSION_MINOR=${MIR_VERSION_MINOR}) |
13 | |
14 | === modified file 'debian/changelog' |
15 | --- debian/changelog 2016-02-25 12:03:41 +0000 |
16 | +++ debian/changelog 2016-03-07 15:15:54 +0000 |
17 | @@ -1,3 +1,14 @@ |
18 | +mir (0.20.2) UNRELEASED; urgency=medium |
19 | + |
20 | + * New upstream release 0.20.2 (https://launchpad.net/mir/+milestone/0.20.2) |
21 | + - ABI summary: |
22 | + . No ABI changes in any libraries. Bugfix release only. |
23 | + - Bug fixed: |
24 | + . On removal of USB and BT devices key repeat events of pressed keys |
25 | + are sent indefinitely. (LP:#1550050) |
26 | + |
27 | + -- Andreas Pokorny <andreas.pokorny@canonical.com> Mon, 07 Mar 2016 10:03:45 +0100 |
28 | + |
29 | mir (0.20.1+16.04.20160225.1-0ubuntu1) xenial; urgency=medium |
30 | |
31 | [ Kevin DuBois ] |
32 | |
33 | === added file 'include/test/mir/test/doubles/mock_input_device_hub.h' |
34 | --- include/test/mir/test/doubles/mock_input_device_hub.h 1970-01-01 00:00:00 +0000 |
35 | +++ include/test/mir/test/doubles/mock_input_device_hub.h 2016-03-07 15:15:54 +0000 |
36 | @@ -0,0 +1,43 @@ |
37 | +/* |
38 | + * Copyright © 2016 Canonical Ltd. |
39 | + * |
40 | + * This program is free software: you can redistribute it and/or modify it |
41 | + * under the terms of the GNU General Public License version 3, |
42 | + * as published by the Free Software Foundation. |
43 | + * |
44 | + * This program is distributed in the hope that it will be useful, |
45 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
46 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
47 | + * GNU General Public License for more details. |
48 | + * |
49 | + * You should have received a copy of the GNU General Public License |
50 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
51 | + * |
52 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
53 | + */ |
54 | + |
55 | +#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_DEVICE_HUB_H_ |
56 | +#define MIR_TEST_DOUBLES_MOCK_INPUT_DEVICE_HUB_H_ |
57 | + |
58 | +#include "mir/input/input_device_hub.h" |
59 | + |
60 | +namespace mir |
61 | +{ |
62 | +namespace test |
63 | +{ |
64 | +namespace doubles |
65 | +{ |
66 | + |
67 | +struct MockInputDeviceHub : input::InputDeviceHub |
68 | +{ |
69 | + MOCK_METHOD1(add_observer, void(std::shared_ptr<input::InputDeviceObserver> const&)); |
70 | + MOCK_METHOD1(remove_observer, void(std::weak_ptr<input::InputDeviceObserver> const&)); |
71 | + MOCK_METHOD1(for_each_input_device, void(std::function<void(std::shared_ptr<input::Device>const&)> const&)); |
72 | + |
73 | +}; |
74 | + |
75 | +} |
76 | +} |
77 | +} |
78 | + |
79 | +#endif |
80 | |
81 | === modified file 'src/server/input/default_configuration.cpp' |
82 | --- src/server/input/default_configuration.cpp 2016-02-12 10:51:29 +0000 |
83 | +++ src/server/input/default_configuration.cpp 2016-03-07 15:15:54 +0000 |
84 | @@ -270,33 +270,46 @@ |
85 | |
86 | std::shared_ptr<mi::InputDeviceRegistry> mir::DefaultServerConfiguration::the_input_device_registry() |
87 | { |
88 | - return default_input_device_hub([this]() |
89 | - { |
90 | - return std::make_shared<mi::DefaultInputDeviceHub>( |
91 | - std::make_shared<mi::BasicSeat>( |
92 | - the_input_dispatcher(), |
93 | - the_touch_visualizer(), |
94 | - the_cursor_listener(), |
95 | - the_input_region()), |
96 | - the_input_reading_multiplexer(), |
97 | - the_main_loop(), |
98 | - the_cookie_authority()); |
99 | - }); |
100 | + return default_input_device_hub( |
101 | + [this]() |
102 | + { |
103 | + auto input_dispatcher = the_input_dispatcher(); |
104 | + auto key_repeater = std::dynamic_pointer_cast<mi::KeyRepeatDispatcher>(input_dispatcher); |
105 | + auto hub = std::make_shared<mi::DefaultInputDeviceHub>( |
106 | + std::make_shared<mi::BasicSeat>( |
107 | + input_dispatcher, |
108 | + the_touch_visualizer(), |
109 | + the_cursor_listener(), |
110 | + the_input_region()), |
111 | + the_input_reading_multiplexer(), |
112 | + the_main_loop(), |
113 | + the_cookie_authority()); |
114 | + |
115 | + if (key_repeater) |
116 | + key_repeater->set_input_device_hub(hub); |
117 | + return hub; |
118 | + }); |
119 | } |
120 | |
121 | std::shared_ptr<mi::InputDeviceHub> mir::DefaultServerConfiguration::the_input_device_hub() |
122 | { |
123 | - return default_input_device_hub([this]() |
124 | - { |
125 | - return std::make_shared<mi::DefaultInputDeviceHub>( |
126 | -std::make_shared<mi::BasicSeat>( |
127 | - the_input_dispatcher(), |
128 | - the_touch_visualizer(), |
129 | - the_cursor_listener(), |
130 | - the_input_region()), |
131 | + return default_input_device_hub( |
132 | + [this]() |
133 | + { |
134 | + auto input_dispatcher = the_input_dispatcher(); |
135 | + auto key_repeater = std::dynamic_pointer_cast<mi::KeyRepeatDispatcher>(input_dispatcher); |
136 | + auto hub = std::make_shared<mi::DefaultInputDeviceHub>( |
137 | + std::make_shared<mi::BasicSeat>( |
138 | + input_dispatcher, |
139 | + the_touch_visualizer(), |
140 | + the_cursor_listener(), |
141 | + the_input_region()), |
142 | + the_input_reading_multiplexer(), |
143 | + the_main_loop(), |
144 | + the_cookie_authority()); |
145 | |
146 | - the_input_reading_multiplexer(), |
147 | - the_main_loop(), |
148 | - the_cookie_authority()); |
149 | - }); |
150 | + if (key_repeater) |
151 | + key_repeater->set_input_device_hub(hub); |
152 | + return hub; |
153 | + }); |
154 | } |
155 | |
156 | === modified file 'src/server/input/default_input_device_hub.cpp' |
157 | --- src/server/input/default_input_device_hub.cpp 2016-01-29 15:55:17 +0000 |
158 | +++ src/server/input/default_input_device_hub.cpp 2016-03-07 15:15:54 +0000 |
159 | @@ -228,17 +228,23 @@ |
160 | |
161 | void mi::DefaultInputDeviceHub::remove_device_handle(MirInputDeviceId id) |
162 | { |
163 | - auto handle_it = remove_if(begin(handles), |
164 | - end(handles), |
165 | - [&id](auto const& handle){return handle->id() == id;}); |
166 | + auto handle_it = remove_if( |
167 | + begin(handles), |
168 | + end(handles), |
169 | + [this,&id](auto const& handle) |
170 | + { |
171 | + if (handle->id() != id) |
172 | + return false; |
173 | + for (auto const& observer : observers) |
174 | + { |
175 | + observer->device_removed(handle); |
176 | + observer->changes_complete(); |
177 | + } |
178 | + return true; |
179 | + }); |
180 | |
181 | if (handle_it == end(handles)) |
182 | return; |
183 | - for (auto const& observer : observers) |
184 | - { |
185 | - observer->device_removed(*handle_it); |
186 | - observer->changes_complete(); |
187 | - } |
188 | |
189 | handles.erase(handle_it, end(handles)); |
190 | } |
191 | |
192 | === modified file 'src/server/input/key_repeat_dispatcher.cpp' |
193 | --- src/server/input/key_repeat_dispatcher.cpp 2016-01-29 08:18:22 +0000 |
194 | +++ src/server/input/key_repeat_dispatcher.cpp 2016-03-07 15:15:54 +0000 |
195 | @@ -18,6 +18,8 @@ |
196 | |
197 | #include "key_repeat_dispatcher.h" |
198 | |
199 | +#include "mir/input/device.h" |
200 | +#include "mir/input/input_device_hub.h" |
201 | #include "mir/time/alarm_factory.h" |
202 | #include "mir/time/alarm.h" |
203 | #include "mir/events/event_private.h" |
204 | @@ -31,6 +33,34 @@ |
205 | |
206 | namespace mi = mir::input; |
207 | |
208 | +namespace |
209 | +{ |
210 | +struct DeviceRemovalFilter : mi::InputDeviceObserver |
211 | +{ |
212 | + DeviceRemovalFilter(std::function<void(MirInputDeviceId)> const& on_removal) |
213 | + : on_removal(on_removal) {} |
214 | + |
215 | + void device_added(std::shared_ptr<mi::Device> const&) override |
216 | + { |
217 | + } |
218 | + |
219 | + void device_changed(std::shared_ptr<mi::Device> const&) override |
220 | + { |
221 | + } |
222 | + |
223 | + void device_removed(std::shared_ptr<mi::Device> const& device) override |
224 | + { |
225 | + on_removal(device->id()); |
226 | + } |
227 | + |
228 | + void changes_complete() override |
229 | + { |
230 | + } |
231 | + std::function<void(MirInputDeviceId)> on_removal; |
232 | +}; |
233 | + |
234 | +} |
235 | + |
236 | mi::KeyRepeatDispatcher::KeyRepeatDispatcher( |
237 | std::shared_ptr<mi::InputDispatcher> const& next_dispatcher, |
238 | std::shared_ptr<mir::time::AlarmFactory> const& factory, |
239 | @@ -47,6 +77,17 @@ |
240 | { |
241 | } |
242 | |
243 | +void mi::KeyRepeatDispatcher::set_input_device_hub(std::shared_ptr<InputDeviceHub> const& hub) |
244 | +{ |
245 | + hub->add_observer(std::make_shared<DeviceRemovalFilter>( |
246 | + [this](MirInputDeviceId id) |
247 | + { |
248 | + std::unique_lock<std::mutex> lock(repeat_state_mutex); |
249 | + repeat_state_by_device.erase(id); // destructor cancels alarms |
250 | + } |
251 | + )); |
252 | +} |
253 | + |
254 | mi::KeyRepeatDispatcher::KeyboardState& mi::KeyRepeatDispatcher::ensure_state_for_device_locked(std::lock_guard<std::mutex> const&, MirInputDeviceId id) |
255 | { |
256 | repeat_state_by_device.insert(std::make_pair(id, KeyboardState())); |
257 | |
258 | === modified file 'src/server/input/key_repeat_dispatcher.h' |
259 | --- src/server/input/key_repeat_dispatcher.h 2016-01-29 08:18:22 +0000 |
260 | +++ src/server/input/key_repeat_dispatcher.h 2016-03-07 15:15:54 +0000 |
261 | @@ -1,5 +1,5 @@ |
262 | /* |
263 | - * Copyright © 2015 Canonical Ltd. |
264 | + * Copyright © 2015-2016 Canonical Ltd. |
265 | * |
266 | * This program is free software: you can redistribute it and/or modify it |
267 | * under the terms of the GNU General Public License version 3, |
268 | @@ -20,6 +20,7 @@ |
269 | #define MIR_INPUT_KEY_REPEAT_DISPATCHER_H_ |
270 | |
271 | #include "mir/input/input_dispatcher.h" |
272 | +#include "mir/input/input_device_observer.h" |
273 | |
274 | #include <memory> |
275 | #include <chrono> |
276 | @@ -39,8 +40,8 @@ |
277 | } |
278 | namespace input |
279 | { |
280 | - |
281 | -class KeyRepeatDispatcher : public mir::input::InputDispatcher |
282 | +class InputDeviceHub; |
283 | +class KeyRepeatDispatcher : public InputDispatcher |
284 | { |
285 | public: |
286 | KeyRepeatDispatcher(std::shared_ptr<InputDispatcher> const& next_dispatcher, |
287 | @@ -54,7 +55,9 @@ |
288 | bool dispatch(MirEvent const& event) override; |
289 | void start() override; |
290 | void stop() override; |
291 | - |
292 | + |
293 | + void set_input_device_hub(std::shared_ptr<InputDeviceHub> const& hub); |
294 | + |
295 | private: |
296 | std::mutex repeat_state_mutex; |
297 | |
298 | |
299 | === modified file 'tests/unit-tests/input/test_key_repeat_dispatcher.cpp' |
300 | --- tests/unit-tests/input/test_key_repeat_dispatcher.cpp 2016-01-29 08:18:22 +0000 |
301 | +++ tests/unit-tests/input/test_key_repeat_dispatcher.cpp 2016-03-07 15:15:54 +0000 |
302 | @@ -23,9 +23,15 @@ |
303 | #include "mir/time/alarm.h" |
304 | #include "mir/time/alarm_factory.h" |
305 | #include "mir/cookie/authority.h" |
306 | +#include "mir/input/input_device_observer.h" |
307 | +#include "mir/input/pointer_configuration.h" |
308 | +#include "mir/input/touchpad_configuration.h" |
309 | +#include "mir/input/device.h" |
310 | |
311 | +#include "mir/test/fake_shared.h" |
312 | #include "mir/test/event_matchers.h" |
313 | #include "mir/test/doubles/mock_input_dispatcher.h" |
314 | +#include "mir/test/doubles/mock_input_device_hub.h" |
315 | |
316 | #include <gtest/gtest.h> |
317 | #include <gmock/gmock.h> |
318 | @@ -35,6 +41,8 @@ |
319 | namespace mt = mir::test; |
320 | namespace mtd = mt::doubles; |
321 | |
322 | +using namespace ::testing; |
323 | + |
324 | namespace |
325 | { |
326 | struct MockAlarm : public mir::time::Alarm |
327 | @@ -43,6 +51,12 @@ |
328 | MOCK_CONST_METHOD0(state, mir::time::Alarm::State()); |
329 | MOCK_METHOD1(reschedule_in, bool(std::chrono::milliseconds)); |
330 | MOCK_METHOD1(reschedule_for, bool(mir::time::Timestamp)); |
331 | + |
332 | + // destructor cancels the alarm |
333 | + ~MockAlarm() |
334 | + { |
335 | + cancel(); |
336 | + } |
337 | }; |
338 | |
339 | struct MockAlarmFactory : public mir::time::AlarmFactory |
340 | @@ -59,25 +73,60 @@ |
341 | } |
342 | }; |
343 | |
344 | +struct StubDevice : public mi::Device |
345 | +{ |
346 | + MirInputDeviceId device_id; |
347 | + StubDevice(MirInputDeviceId id) : device_id(id) {} |
348 | + MirInputDeviceId id() const { return device_id;} |
349 | + mi::DeviceCapabilities capabilities() const {return mi::DeviceCapability::keyboard;} |
350 | + std::string name() const {return {};} |
351 | + std::string unique_id() const {return {};} |
352 | + |
353 | + mir::optional_value<mi::PointerConfiguration> pointer_configuration() const {return {};} |
354 | + void apply_pointer_configuration(mi::PointerConfiguration const&) {;} |
355 | + mir::optional_value<mi::TouchpadConfiguration> touchpad_configuration() const {return {};} |
356 | + void apply_touchpad_configuration(mi::TouchpadConfiguration const&) {} |
357 | +}; |
358 | + |
359 | struct KeyRepeatDispatcher : public testing::Test |
360 | { |
361 | KeyRepeatDispatcher() |
362 | : dispatcher(mock_next_dispatcher, mock_alarm_factory, cookie_authority, true, repeat_time, repeat_delay) |
363 | { |
364 | - } |
365 | + ON_CALL(hub,add_observer(_)).WillByDefault(SaveArg<0>(&observer)); |
366 | + dispatcher.set_input_device_hub(mt::fake_shared(hub)); |
367 | + } |
368 | + void simulate_device_removal() |
369 | + { |
370 | + StubDevice dev(test_device); |
371 | + observer->device_removed(mt::fake_shared(dev)); |
372 | + observer->changes_complete(); |
373 | + } |
374 | + |
375 | + const MirInputDeviceId test_device = 123; |
376 | std::shared_ptr<mtd::MockInputDispatcher> mock_next_dispatcher = std::make_shared<mtd::MockInputDispatcher>(); |
377 | std::shared_ptr<MockAlarmFactory> mock_alarm_factory = std::make_shared<MockAlarmFactory>(); |
378 | std::shared_ptr<mir::cookie::Authority> cookie_authority = mir::cookie::Authority::create(); |
379 | std::chrono::milliseconds const repeat_time{2}; |
380 | std::chrono::milliseconds const repeat_delay{1}; |
381 | + std::shared_ptr<mi::InputDeviceObserver> observer; |
382 | + NiceMock<mtd::MockInputDeviceHub> hub; |
383 | mi::KeyRepeatDispatcher dispatcher; |
384 | + |
385 | + mir::EventUPtr a_key_down_event() |
386 | + { |
387 | + return mev::make_event(test_device, std::chrono::nanoseconds(0), std::vector<uint8_t>{}, mir_keyboard_action_down, 0, 0, mir_input_event_modifier_alt); |
388 | + } |
389 | + |
390 | + mir::EventUPtr a_key_up_event() |
391 | + { |
392 | + return mev::make_event(test_device, std::chrono::nanoseconds(0), std::vector<uint8_t>{}, mir_keyboard_action_up, 0, 0, mir_input_event_modifier_alt); |
393 | + } |
394 | }; |
395 | } |
396 | |
397 | TEST_F(KeyRepeatDispatcher, forwards_start_stop) |
398 | { |
399 | - using namespace ::testing; |
400 | - |
401 | InSequence seq; |
402 | EXPECT_CALL(*mock_next_dispatcher, start()).Times(1); |
403 | EXPECT_CALL(*mock_next_dispatcher, stop()).Times(1); |
404 | @@ -86,22 +135,8 @@ |
405 | dispatcher.stop(); |
406 | } |
407 | |
408 | -namespace |
409 | -{ |
410 | -mir::EventUPtr a_key_down_event() |
411 | -{ |
412 | - return mev::make_event(0, std::chrono::nanoseconds(0), std::vector<uint8_t>{}, mir_keyboard_action_down, 0, 0, mir_input_event_modifier_alt); |
413 | -} |
414 | -mir::EventUPtr a_key_up_event() |
415 | -{ |
416 | - return mev::make_event(0, std::chrono::nanoseconds(0), std::vector<uint8_t>{}, mir_keyboard_action_up, 0, 0, mir_input_event_modifier_alt); |
417 | -} |
418 | -} |
419 | - |
420 | TEST_F(KeyRepeatDispatcher, schedules_alarm_to_repeat_key_down) |
421 | { |
422 | - using namespace ::testing; |
423 | - |
424 | MockAlarm *mock_alarm = new MockAlarm; // deleted by AlarmFactory |
425 | std::function<void()> alarm_function; |
426 | |
427 | @@ -122,3 +157,28 @@ |
428 | // Trigger the cancel |
429 | dispatcher.dispatch(*a_key_up_event()); |
430 | } |
431 | + |
432 | +TEST_F(KeyRepeatDispatcher, stops_repeat_on_device_removal) |
433 | +{ |
434 | + MockAlarm *mock_alarm = new MockAlarm; |
435 | + std::function<void()> alarm_function; |
436 | + bool alarm_canceled = false; |
437 | + |
438 | + InSequence seq; |
439 | + EXPECT_CALL(*mock_alarm_factory, create_alarm_adapter(_)).Times(1). |
440 | + WillOnce(DoAll(SaveArg<0>(&alarm_function), Return(mock_alarm))); |
441 | + // Once for initial down and again when invoked |
442 | + EXPECT_CALL(*mock_alarm, reschedule_in(repeat_time)).Times(1).WillOnce(Return(true)); |
443 | + EXPECT_CALL(*mock_next_dispatcher, dispatch(mt::KeyDownEvent())).Times(1); |
444 | + EXPECT_CALL(*mock_next_dispatcher, dispatch(mt::KeyRepeatEvent())).Times(1); |
445 | + EXPECT_CALL(*mock_alarm, reschedule_in(repeat_delay)).Times(1).WillOnce(Return(true)); |
446 | + ON_CALL(*mock_alarm, cancel()).WillByDefault(Invoke([&](){alarm_canceled = true; return true;})); |
447 | + |
448 | + dispatcher.dispatch(*a_key_down_event()); |
449 | + |
450 | + alarm_function(); |
451 | + Mock::VerifyAndClearExpectations(mock_alarm); // mock_alarm will be deleted after this |
452 | + |
453 | + simulate_device_removal(); |
454 | + EXPECT_THAT(alarm_canceled, Eq(true)); |
455 | +} |
FAILED: Continuous integration, rev:3332 /mir-jenkins. ubuntu. com/job/ mir-ubuntu- ci/2/ /mir-jenkins. ubuntu. com/job/ build-mir/ 347/console /mir-jenkins. ubuntu. com/job/ build-0- fetch/377 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 369 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial/ 369 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= vivid+overlay/ 356/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial/ 356 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial/ 356/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 356/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 356/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 356/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial/ 356 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial/ 356/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ mir-ubuntu- ci/2/rebuild
https:/