Mir

Merge lp:~andreas-pokorny/mir/cleanup-event-input-transport-conversion into lp:mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 3203
Proposed branch: lp:~andreas-pokorny/mir/cleanup-event-input-transport-conversion
Merge into: lp:mir
Diff against target: 430 lines (+167/-96)
5 files modified
src/client/symbols.map (+1/-0)
src/server/input/android/input_send_entry.h (+4/-4)
src/server/input/android/input_sender.cpp (+122/-83)
src/server/input/android/input_sender.h (+4/-3)
tests/unit-tests/input/android/test_android_input_sender.cpp (+36/-6)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/cleanup-event-input-transport-conversion
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Alberto Aguirre (community) Approve
Alan Griffiths Needs Information
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+280075@code.launchpad.net

Commit message

android-input-sender Ensure tool type and source properties are correctly set when transferred to InputTransport

With the tooltype set to mouse, InputConsumer will not try to interpolate batched pointer movements.
Additionally this removes some more uses of event_private.h.

Description of the change

This MP is motivated by an attempt to match expectations built into InputConsumer. mir::input::android::InputSender passes MirEvent over to InputTransport. This change ensures that the android representation contains additional fields tested by InputConsumer like the tooltype and source id. With that InputConsumer will not interpolate mouse coordinates.

Additionally to this MP follows the boy scout rule and removes ugly parts from InputSender.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(1) Wrong stanza. New functions should go in MIR_CLIENT_unreleased.

54 +++ src/client/symbols.map 2015-12-09 20:53:14 +0000
55 @@ -66,6 +66,7 @@
56 mir_input_event_get_device_id;
57 mir_input_event_get_event_time;
58 mir_input_event_get_keyboard_event;
59 + mir_input_event_get_mac;

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

hmm fd leaks.. this needs more fixing..

Revision history for this message
Daniel van Vugt (vanvugt) :
review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Comments inline.

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

Is this related to either of the remaining bugs?
https://bugs.launchpad.net/mir/+bugs?field.tag=pointer-events

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

No that mp does not extend the udev hwdb with antother high frequency/high dpi mouse. But it will make sure that InputConsumer sees that the coordinates are generated from a pointing/mouse device.

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

+typedef uint64_t MirInputEventMac;

Why is this being introduced? (I thought the MAC is going to be larger than uint64_t when surfaced in the client API.)

review: Needs Information
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> +typedef uint64_t MirInputEventMac;
>
> Why is this being introduced? (I thought the MAC is going to be larger than
> uint64_t when surfaced in the client API.)

Right this is not needed. I removed the code that used that from the MP after talking to bschaefer.. but missed that part

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:3195
http://jenkins.qa.ubuntu.com/job/mir-ci/5841/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5302
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4208
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5251
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/152/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/169
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/169/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/169
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/169/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5251
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5251/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/7771
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26015
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/150
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/150/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/9/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26019

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/5841/rebuild

review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

It sounds theoretically like the right thing to do.

Is there any manual test case where one could notice any difference in behaviour yet?

The description seems to suggest that this should change the behaviour observed with mice? I see no change yet when testing it...

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

Looks sensible, but I've always been nervous about touching this code as it has very poor test coverage. How easy would it be to land some tests first to prove nothing breaks?

review: Needs Information
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> It sounds theoretically like the right thing to do.
>
> Is there any manual test case where one could notice any difference in
> behaviour yet?
>
> The description seems to suggest that this should change the behaviour
> observed with mice? I see no change yet when testing it...

There is a slight behaviour change.. when acceleration is on and input rate is limited. There is no linear interpolation between two samples.. But that is not easy to spot. Yes resampling / batching lacks tests..

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> Looks sensible, but I've always been nervous about touching this code as it
> has very poor test coverage. How easy would it be to land some tests first to
> prove nothing breaks?

I guess the ones we would care about here, would be tests that include the client side input receiver? I will see what I can do..

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I was guessing it should be possible to spot a difference in fingerpaint, but could not see any.

review: Abstain
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Ok, comments have been addressed.

LGTM.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Wait, no, resampling and batching already has tests. I remember writing them.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/client/symbols.map'
2--- src/client/symbols.map 2015-12-02 19:59:55 +0000
3+++ src/client/symbols.map 2015-12-14 10:36:23 +0000
4@@ -250,6 +250,7 @@
5 mir::events::set_modifier*;
6 mir::events::set_cursor_position*;
7 mir::events::set_button_state*;
8+ mir::input::android::android_pointer_action_from_mir*;
9 };
10 } MIR_CLIENT_DETAIL_9;
11
12
13=== modified file 'src/server/input/android/input_send_entry.h'
14--- src/server/input/android/input_send_entry.h 2015-08-14 14:51:26 +0000
15+++ src/server/input/android/input_send_entry.h 2015-12-14 10:36:23 +0000
16@@ -20,7 +20,6 @@
17 #define MIR_INPUT_ANDROID_INPUT_SEND_ENTRY_H_
18
19 #include "mir_toolkit/event.h"
20-#include "mir/events/event_private.h"
21
22 #include <memory>
23
24@@ -38,10 +37,11 @@
25 struct InputSendEntry
26 {
27 uint32_t sequence_id;
28- MirEvent event;
29+ using EventPtr = std::unique_ptr<MirEvent const, void(*)(MirEvent const*)>;
30+ EventPtr event;
31 std::shared_ptr<InputChannel> channel;
32- InputSendEntry(uint32_t id, MirEvent ev, std::shared_ptr<InputChannel> const& channel)
33- : sequence_id(id), event(ev), channel(channel)
34+ InputSendEntry(uint32_t id, MirEvent const& ev, std::shared_ptr<InputChannel> const& channel)
35+ : sequence_id(id), event(mir_event_ref(&ev), mir_event_unref), channel(channel)
36 {
37 }
38 };
39
40=== modified file 'src/server/input/android/input_sender.cpp'
41--- src/server/input/android/input_sender.cpp 2015-12-11 03:18:13 +0000
42+++ src/server/input/android/input_sender.cpp 2015-12-14 10:36:23 +0000
43@@ -27,6 +27,7 @@
44 #include "mir/scene/surface.h"
45 #include "mir/compositor/scene.h"
46 #include "mir/main_loop.h"
47+#include "mir/events/event_private.h"
48
49 #include <boost/exception/errinfo_errno.hpp>
50 #include <boost/throw_exception.hpp>
51@@ -174,22 +175,29 @@
52
53 void mia::InputSender::ActiveTransfer::send(InputSendEntry && event)
54 {
55- if (event.event.type != mir_event_type_key &&
56- event.event.type != mir_event_type_motion)
57+ if (mir_event_get_type(event.event.get()) != mir_event_type_input)
58 return;
59
60 droidinput::status_t error_status;
61
62- auto event_time = mir_input_event_get_event_time(mir_event_get_input_event(&event.event));
63- if (event.event.type == mir_event_type_key)
64+ auto event_time = mir_input_event_get_event_time(mir_event_get_input_event(event.event.get()));
65+ auto input_event = mir_event_get_input_event(event.event.get());
66+ switch(mir_input_event_get_type(input_event))
67 {
68- error_status = send_key_event(event.sequence_id, event.event.key);
69+ case mir_input_event_type_key:
70+ error_status = send_key_event(event.sequence_id, *event.event);
71 state.report->published_key_event(event.channel->server_fd(), event.sequence_id, event_time);
72- }
73- else
74- {
75- error_status = send_motion_event(event.sequence_id, event.event.motion);
76- state.report->published_motion_event(event.channel->server_fd(), event.sequence_id, event_time);
77+ break;
78+ case mir_input_event_type_touch:
79+ error_status = send_touch_event(event.sequence_id, *event.event);
80+ state.report->published_motion_event(event.channel->server_fd(), event.sequence_id, event_time);
81+ break;
82+ case mir_input_event_type_pointer:
83+ error_status = send_pointer_event(event.sequence_id, *event.event);
84+ state.report->published_motion_event(event.channel->server_fd(), event.sequence_id, event_time);
85+ break;
86+ default:
87+ BOOST_THROW_EXCEPTION(std::runtime_error("unknown input event type"));
88 }
89
90 if (error_status == droidinput::OK)
91@@ -202,11 +210,11 @@
92 {
93 case droidinput::WOULD_BLOCK:
94 if (state.observer)
95- state.observer->client_blocked(event.event, surface);
96+ state.observer->client_blocked(*event.event, surface);
97 break;
98 case droidinput::DEAD_OBJECT:
99 if (state.observer)
100- state.observer->send_failed(event.event, surface, InputSendObserver::socket_error);
101+ state.observer->send_failed(*event.event, surface, InputSendObserver::socket_error);
102 break;
103 default:
104 BOOST_THROW_EXCEPTION(boost::enable_error_info(std::runtime_error("Failure sending input event : ")) << boost::errinfo_errno(errno));
105@@ -238,73 +246,97 @@
106 });
107 }
108
109-droidinput::status_t mia::InputSender::ActiveTransfer::send_key_event(uint32_t seq, MirKeyboardEvent const& event)
110+droidinput::status_t mia::InputSender::ActiveTransfer::send_key_event(uint32_t seq, MirEvent const& event)
111 {
112 int32_t repeat_count = 0;
113- auto android_action = mia::android_keyboard_action_from_mir(repeat_count, event.action);
114- return publisher.publishKeyEvent(
115- seq,
116- event.device_id,
117- event.source_id,
118- android_action,
119- 0, /* Flags */
120- event.key_code,
121- event.scan_code,
122- mia::android_modifiers_from_mir(event.modifiers),
123- repeat_count,
124- event.mac,
125- event.event_time,
126- event.event_time
127- );
128+ auto input_event = mir_event_get_input_event(&event);
129+ auto key_event = mir_input_event_get_keyboard_event(input_event);
130+ auto const android_action = mia::android_keyboard_action_from_mir(repeat_count, mir_keyboard_event_action(key_event));
131+ std::chrono::nanoseconds const event_time{mir_input_event_get_event_time(input_event)};
132+ auto const flags = 0;
133+ return publisher.publishKeyEvent(seq,
134+ mir_input_event_get_device_id(input_event),
135+ AINPUT_SOURCE_KEYBOARD,
136+ android_action,
137+ flags,
138+ mir_keyboard_event_key_code(key_event),
139+ mir_keyboard_event_scan_code(key_event),
140+ mia::android_modifiers_from_mir(mir_keyboard_event_modifiers(key_event)),
141+ repeat_count,
142+ event.key.mac,
143+ event_time,
144+ event_time);
145 }
146
147-droidinput::status_t mia::InputSender::ActiveTransfer::send_motion_event(uint32_t seq, MirMotionEvent const& event)
148+droidinput::status_t mia::InputSender::ActiveTransfer::send_touch_event(uint32_t seq, MirEvent const& event)
149 {
150 droidinput::PointerCoords coords[MIR_INPUT_EVENT_MAX_POINTER_COUNT];
151 droidinput::PointerProperties properties[MIR_INPUT_EVENT_MAX_POINTER_COUNT];
152- // no default constructor:
153- std::memset(coords, 0, sizeof(coords));
154- std::memset(properties, 0, sizeof(properties));
155+ std::memset(&coords, 0, sizeof(coords));
156+ std::memset(&properties, 0, sizeof(properties));
157
158- for (size_t i = 0; i < event.pointer_count; ++i)
159+ auto input_event = mir_event_get_input_event(&event);
160+ auto touch = mir_input_event_get_touch_event(input_event);
161+ for (size_t i = 0, e = mir_touch_event_point_count(touch); i != e; ++i)
162 {
163 // Note: this assumes that: x == raw_x + x_offset;
164 // here x, y is used instead of the raw co-ordinates and offset is set to zero
165- coords[i].setAxisValue(AMOTION_EVENT_AXIS_X, event.pointer_coordinates[i].x);
166- coords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, event.pointer_coordinates[i].y);
167- coords[i].setAxisValue(AMOTION_EVENT_AXIS_RX, event.pointer_coordinates[i].dx);
168- coords[i].setAxisValue(AMOTION_EVENT_AXIS_RY, event.pointer_coordinates[i].dy);
169-
170- coords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, event.pointer_coordinates[i].touch_major);
171- coords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, event.pointer_coordinates[i].touch_minor);
172- coords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, event.pointer_coordinates[i].size);
173- coords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, event.pointer_coordinates[i].pressure);
174- coords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, event.pointer_coordinates[i].orientation);
175- coords[i].setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, event.pointer_coordinates[i].vscroll);
176- coords[i].setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, event.pointer_coordinates[i].hscroll);
177- properties[i].toolType = mia::android_tool_type_from_mir(event.pointer_coordinates[i].tool_type);
178- properties[i].id = event.pointer_coordinates[i].id;
179+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_X, mir_touch_event_axis_value(touch, i, mir_touch_axis_x));
180+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, mir_touch_event_axis_value(touch, i, mir_touch_axis_y));
181+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, mir_touch_event_axis_value(touch, i, mir_touch_axis_touch_major));
182+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, mir_touch_event_axis_value(touch, i, mir_touch_axis_touch_minor));
183+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, mir_touch_event_axis_value(touch, i, mir_touch_axis_size));
184+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure));
185+ properties[i].toolType = mia::android_tool_type_from_mir(mir_touch_event_tooltype(touch, i));
186+ properties[i].id = mir_touch_event_id(touch, i);
187 }
188
189+ std::chrono::nanoseconds const event_time{mir_input_event_get_event_time(input_event)};
190+ auto const x_offset = 0.0f;
191+ auto const y_offset = 0.0f;
192+ auto const x_precision = 0;
193+ auto const y_precision = 0;
194+ auto const flags = 0;
195+ auto const edge_flags = 0;
196+ auto const button_state = 0;
197+ return publisher.publishMotionEvent(seq, mir_input_event_get_device_id(input_event), AINPUT_SOURCE_TOUCHSCREEN,
198+ mia::extract_android_action_from(event), flags, edge_flags,
199+ mia::android_modifiers_from_mir(mir_touch_event_modifiers(touch)), button_state,
200+ x_offset, y_offset, x_precision, y_precision, event.motion.mac, event_time,
201+ event_time, mir_touch_event_point_count(touch), properties, coords);
202+}
203+
204+droidinput::status_t mia::InputSender::ActiveTransfer::send_pointer_event(uint32_t seq, MirEvent const& event)
205+{
206+ droidinput::PointerCoords pointer_coord;
207+ droidinput::PointerProperties pointer_properties;
208+ std::memset(&pointer_coord, 0, sizeof(pointer_coord));
209+ std::memset(&pointer_properties, 0, sizeof(pointer_properties));
210+
211+ auto input_event = mir_event_get_input_event(&event);
212+ auto pointer = mir_input_event_get_pointer_event(input_event);
213+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_X, mir_pointer_event_axis_value(pointer, mir_pointer_axis_x));
214+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_Y, mir_pointer_event_axis_value(pointer, mir_pointer_axis_y));
215+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll));
216+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll));
217+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_RX, mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_x));
218+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_RY, mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_y));
219+ pointer_properties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
220+ pointer_properties.id = 0;
221+
222+ std::chrono::nanoseconds const event_time{mir_input_event_get_event_time(input_event)};
223+ auto const x_offset = 0.0f;
224+ auto const y_offset = 0.0f;
225+ auto const x_precision = 0;
226+ auto const y_precision = 0;
227+ auto const flags = 0;
228+ auto const edge_flags = 0;
229 return publisher.publishMotionEvent(
230- seq,
231- event.device_id,
232- event.source_id,
233- mia::extract_android_action_from(reinterpret_cast<MirEvent const&>(event)),
234- 0, /* flags */
235- 0, /* edge flags */
236- mia::android_modifiers_from_mir(event.modifiers),
237- mia::android_pointer_buttons_from_mir(event.buttons),
238- 0.0f, // event.x_offset,
239- 0.0f, // event.y_offset,
240- 0, 0, /* unused x/y precision */
241- event.mac,
242- event.event_time,
243- event.event_time,
244- event.pointer_count,
245- properties,
246- coords
247- );
248+ seq, mir_input_event_get_device_id(input_event), AINPUT_SOURCE_MOUSE,
249+ mia::android_pointer_action_from_mir(mir_pointer_event_action(pointer), mir_pointer_event_buttons(pointer)),
250+ flags, edge_flags, mia::android_modifiers_from_mir(mir_pointer_event_modifiers(pointer)),
251+ mia::android_pointer_buttons_from_mir(mir_pointer_event_buttons(pointer)), x_offset, y_offset, x_precision,
252+ y_precision, event.motion.mac, event_time, event_time, 1, &pointer_properties, &pointer_coord);
253 }
254
255 void mia::InputSender::ActiveTransfer::on_surface_disappeared()
256@@ -323,7 +355,7 @@
257 release_pending_responses.rend(),
258 [observer,this](InputSendEntry const& entry)
259 {
260- observer->send_failed(entry.event, surface, InputSendObserver::surface_disappeared);
261+ observer->send_failed(*entry.event, surface, InputSendObserver::surface_disappeared);
262 });
263 }
264 }
265@@ -340,13 +372,16 @@
266 if (status == droidinput::OK)
267 {
268 state.report->received_event_finished_signal(publisher.getChannel()->getFd(), sequence);
269- InputSendEntry entry = unqueue_entry(sequence);
270- auto observer = state.observer;
271-
272- if (entry.sequence_id == sequence && observer)
273- observer->send_suceeded(entry.event,
274- surface,
275- handled ? InputSendObserver::consumed : InputSendObserver::not_consumed);
276+ unqueue_entry(
277+ sequence,
278+ [observer = state.observer,this,handled](InputSendEntry const& entry)
279+ {
280+ if(observer)
281+ observer->send_suceeded(
282+ *entry.event,
283+ surface,
284+ handled ? InputSendObserver::consumed : InputSendObserver::not_consumed);
285+ });
286 }
287 else
288 {
289@@ -367,10 +402,12 @@
290 top_sequence_id = pending_responses.front().sequence_id;
291 }
292
293- mia::InputSendEntry timedout_entry{unqueue_entry(top_sequence_id)};
294-
295- if (state.observer)
296- state.observer->send_failed(timedout_entry.event, surface, InputSendObserver::no_response_received);
297+ unqueue_entry(top_sequence_id,
298+ [observer = state.observer, this](InputSendEntry const& entry)
299+ {
300+ if(observer)
301+ observer->send_failed(*entry.event, surface, InputSendObserver::no_response_received);
302+ });
303 }
304
305 void mia::InputSender::ActiveTransfer::enqueue_entry(mia::InputSendEntry && entry)
306@@ -383,21 +420,21 @@
307 update_timer();
308 }
309
310- pending_responses.push_back(entry);
311+ pending_responses.emplace_back(std::move(entry));
312 }
313
314-mia::InputSendEntry mia::InputSender::ActiveTransfer::unqueue_entry(uint32_t sequence_id)
315+void mia::InputSender::ActiveTransfer::unqueue_entry(uint32_t sequence_id, std::function<void(InputSendEntry const&)> const& execute_on_entry)
316 {
317- std::lock_guard<std::mutex> lock(transfer_mutex);
318+ std::unique_lock<std::mutex> lock(transfer_mutex);
319 auto pos = std::find_if(pending_responses.begin(),
320 pending_responses.end(),
321 [sequence_id](mia::InputSendEntry const& entry)
322 { return entry.sequence_id == sequence_id; });
323
324 if (pos == end(pending_responses))
325- return {0, MirEvent{}, std::shared_ptr<mi::InputChannel>()};
326+ return;
327
328- mia::InputSendEntry result = *pos;
329+ mia::InputSendEntry result = std::move(*pos);
330 pending_responses.erase(pos);
331 if (pending_responses.empty())
332 {
333@@ -408,7 +445,9 @@
334 update_timer();
335 }
336
337- return result;
338+ lock.unlock();
339+
340+ execute_on_entry(result);
341 }
342
343 void mia::InputSender::ActiveTransfer::update_timer()
344
345=== modified file 'src/server/input/android/input_sender.h'
346--- src/server/input/android/input_sender.h 2015-12-11 03:18:13 +0000
347+++ src/server/input/android/input_sender.h 2015-12-14 10:36:23 +0000
348@@ -100,9 +100,10 @@
349 void on_response_timeout();
350 void update_timer();
351 void cancel_timer();
352- droidinput::status_t send_key_event(uint32_t sequence_id, MirKeyboardEvent const& event);
353- droidinput::status_t send_motion_event(uint32_t sequence_id, MirMotionEvent const& event);
354- InputSendEntry unqueue_entry(uint32_t sequence_id);
355+ droidinput::status_t send_key_event(uint32_t sequence_id, MirEvent const& event);
356+ droidinput::status_t send_touch_event(uint32_t sequence_id, MirEvent const& event);
357+ droidinput::status_t send_pointer_event(uint32_t sequence_id, MirEvent const& event);
358+ void unqueue_entry(uint32_t sequence_id, std::function<void(InputSendEntry const&)> const& do_with_unqued);
359 void enqueue_entry(InputSendEntry && entry);
360
361 InputSenderState & state;
362
363=== modified file 'tests/unit-tests/input/android/test_android_input_sender.cpp'
364--- tests/unit-tests/input/android/test_android_input_sender.cpp 2015-12-11 03:18:13 +0000
365+++ tests/unit-tests/input/android/test_android_input_sender.cpp 2015-12-14 10:36:23 +0000
366@@ -99,13 +99,21 @@
367 public:
368 int const test_scan_code = 32;
369 size_t const test_pointer_count = 2;
370- float test_x_coord[2] = {12, 23};
371- float test_y_coord[2] = {17, 9};
372-
373+ float const test_x_coord[2] = {12, 23};
374+ float const test_y_coord[2] = {17, 9};
375+ mir::geometry::Point const pos{100, 100};
376+ mir::geometry::Displacement const movement{10, -10};
377+
378 AndroidInputSender()
379- : key_event(mev::make_event(MirInputDeviceId(), std::chrono::nanoseconds(1), 0, mir_keyboard_action_down,
380- 7, test_scan_code, mir_input_event_modifier_none)),
381- motion_event(mev::make_event(MirInputDeviceId(), std::chrono::nanoseconds(-1), 0, mir_input_event_modifier_none))
382+ : key_event(mev::make_event(MirInputDeviceId(), std::chrono::nanoseconds(1), 0, mir_keyboard_action_down, 7,
383+ test_scan_code, mir_input_event_modifier_none)),
384+ motion_event(
385+ mev::make_event(MirInputDeviceId(), std::chrono::nanoseconds(-1), 0, mir_input_event_modifier_none)),
386+ pointer_event(mev::make_event(MirInputDeviceId(), std::chrono::nanoseconds(123), 0,
387+ mir_input_event_modifier_none, mir_pointer_action_motion,
388+ mir_pointer_button_primary, pos.x.as_float(), pos.y.as_float(), 0.0f, 0.0f,
389+ movement.dx.as_float(), movement.dy.as_float()))
390+
391 {
392 using namespace ::testing;
393
394@@ -139,6 +147,7 @@
395
396 mir::EventUPtr key_event;
397 mir::EventUPtr motion_event;
398+ mir::EventUPtr pointer_event;
399
400 droidinput::MotionEvent client_motion_event;
401 droidinput::KeyEvent client_key_event;
402@@ -260,7 +269,28 @@
403 EXPECT_EQ(test_x_coord[i], client_motion_event.getX(i)) << "When i=" << i;
404 EXPECT_EQ(test_y_coord[i], client_motion_event.getRawY(i)) << "When i=" << i;
405 EXPECT_EQ(test_y_coord[i], client_motion_event.getY(i)) << "When i=" << i;
406+ EXPECT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, client_motion_event.getToolType(i)) << "When i=" << i;
407 }
408+ EXPECT_EQ(AINPUT_SOURCE_TOUCHSCREEN, client_motion_event.getSource());
409+}
410+
411+TEST_F(AndroidInputSender, sends_pointer_events)
412+{
413+ using namespace ::testing;
414+ register_surface();
415+
416+ sender.send_event(*pointer_event, channel);
417+
418+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(-1), &seq, &event));
419+
420+ EXPECT_EQ(1, client_motion_event.getPointerCount());
421+
422+ EXPECT_EQ(pos.x.as_float(), client_motion_event.getX(0));
423+ EXPECT_EQ(pos.y.as_float(), client_motion_event.getY(0));
424+ EXPECT_EQ(movement.dx.as_float(), client_motion_event.getAxisValue(AMOTION_EVENT_AXIS_RX, 0));
425+ EXPECT_EQ(movement.dy.as_float(), client_motion_event.getAxisValue(AMOTION_EVENT_AXIS_RY, 0));
426+ EXPECT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, client_motion_event.getToolType(0));
427+ EXPECT_EQ(AINPUT_SOURCE_MOUSE, client_motion_event.getSource());
428 }
429
430 TEST_F(AndroidInputSender, response_keeps_fd_registered)

Subscribers

People subscribed via source and target branches