Mir

Merge lp:mir/0.18 into lp:mir/ubuntu

Proposed by Andreas Pokorny
Status: Merged
Merged at revision: 1254
Proposed branch: lp:mir/0.18
Merge into: lp:mir/ubuntu
Diff against target: 654 lines (+404/-67)
13 files modified
CMakeLists.txt (+1/-1)
debian/changelog (+13/-0)
src/client/symbols.map (+7/-0)
src/platforms/mesa/server/kms/platform_symbols.cpp (+19/-1)
src/renderers/gl/program_family.cpp (+0/-5)
src/renderers/gl/renderer.cpp (+4/-1)
src/server/input/android/input_sender.cpp (+152/-8)
src/server/input/android/input_sender.h (+4/-0)
tests/unit-tests/graphics/mesa/kms/test_platform.cpp (+20/-0)
tests/unit-tests/input/android/test_android_input_sender.cpp (+165/-1)
tests/unit-tests/renderers/gl/CMakeLists.txt (+0/-1)
tests/unit-tests/renderers/gl/test_gl_program_family.cpp (+0/-49)
tests/unit-tests/renderers/gl/test_gl_renderer.cpp (+19/-0)
To merge this branch: bzr merge lp:mir/0.18
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Abstain
Review via email: mp+282719@code.launchpad.net

Commit message

Mir release 0.18.1

Description of the change

Mir release 0.18.1

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
Cemil Azizoglu (cemil-azizoglu) wrote :
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 :

(1) changelog has one too many blank lines

(2) I think there are more fixes ready in lp:mir that we could backport here:
https://launchpad.net/mir/+milestone/0.18.1

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

Fixed

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)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-12-03 16:20:03 +0000
3+++ CMakeLists.txt 2016-01-19 15:49:22 +0000
4@@ -28,7 +28,7 @@
5
6 set(MIR_VERSION_MAJOR 0)
7 set(MIR_VERSION_MINOR 18)
8-set(MIR_VERSION_PATCH 0)
9+set(MIR_VERSION_PATCH 1)
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 2015-12-16 18:24:40 +0000
16+++ debian/changelog 2016-01-19 15:49:22 +0000
17@@ -1,3 +1,16 @@
18+mir (0.18.1-0ubuntu1) UNRELEASED; urgency=medium
19+
20+ * New upstream release 0.18.1 (https://launchpad.net/mir/+milestone/0.18.1)
21+ - No ABI changes. Bug fix release only.
22+ - Bugs fixed:
23+ . [regression] pinch to zoom not working reliably (LP: #1531517)
24+ . Buffer leak during repeated mirscreencasts causes server to be killed
25+ (LP: #1523900)
26+ . [regression] Mir servers choose graphics-dummy (or no driver at all)
27+ over mesa-kms on a desktop (LP: #1528082)
28+
29+ -- Andreas Pokorny <andreas.pokorny@canonical.com> Fri, 15 Jan 2016 12:18:35 +0100
30+
31 mir (0.18.0+16.04.20151216.1-0ubuntu1) xenial; urgency=medium
32
33 [ Kevin DuBois ]
34
35=== modified file 'src/client/symbols.map'
36--- src/client/symbols.map 2015-12-07 12:35:30 +0000
37+++ src/client/symbols.map 2016-01-19 15:49:22 +0000
38@@ -253,3 +253,10 @@
39 };
40 } MIR_CLIENT_DETAIL_9;
41
42+MIR_CLIENT_DETAIL_9v18v1 {
43+ global:
44+ extern "C++" {
45+ mir::input::android::android_pointer_action_from_mir*;
46+ };
47+} MIR_CLIENT_DETAIL_9v18;
48+
49
50=== modified file 'src/platforms/mesa/server/kms/platform_symbols.cpp'
51--- src/platforms/mesa/server/kms/platform_symbols.cpp 2015-12-16 13:05:17 +0000
52+++ src/platforms/mesa/server/kms/platform_symbols.cpp 2016-01-19 15:49:22 +0000
53@@ -190,7 +190,25 @@
54 if (platform_option_used)
55 return mg::PlatformPriority::best;
56
57- return mg::PlatformPriority::unsupported;
58+ /* We failed to set mastership. However, still on most systems mesa-kms
59+ * is the right driver to choose. Landing here just means the user did
60+ * not specify --vt or is running from ssh. Still in most cases mesa-kms
61+ * is the correct option so give it a go. Better to fail trying to switch
62+ * VTs (and tell the user that) than to refuse to load the correct
63+ * driver at all. (LP: #1528082)
64+ *
65+ * Just make sure we are below PlatformPriority::supported in case
66+ * mesa-x11 or android can be used instead.
67+ *
68+ * TODO: Revisit the priority terminology. having a range of values between
69+ * "supported" and "unsupported" is potentially confusing.
70+ * TODO: Revisit the return code of this function. We document that
71+ * integer values outside the enum are allowed but C++ disallows it
72+ * without a cast. So we should return an int or typedef to int
73+ * instead.
74+ */
75+ return static_cast<mg::PlatformPriority>(
76+ mg::PlatformPriority::supported - 1);
77 }
78
79 mir::ModuleProperties const description = {
80
81=== modified file 'src/renderers/gl/program_family.cpp'
82--- src/renderers/gl/program_family.cpp 2015-09-11 12:29:40 +0000
83+++ src/renderers/gl/program_family.cpp 2016-01-19 15:49:22 +0000
84@@ -19,7 +19,6 @@
85 #include "program_family.h"
86
87 #include <mutex>
88-#include <EGL/egl.h>
89
90 namespace mir
91 {
92@@ -59,10 +58,6 @@
93 // need any reference counting or to worry about how many copy constructions
94 // might have been followed by destructor calls during container resizes.
95
96- // Workaround for lp:1454201. Release any current GL context to avoid crashes
97- // in the glDelete* functions that follow.
98- eglMakeCurrent(eglGetCurrentDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
99-
100 for (auto& p : program)
101 {
102 if (p.second.id)
103
104=== modified file 'src/renderers/gl/renderer.cpp'
105--- src/renderers/gl/renderer.cpp 2015-10-26 13:23:05 +0000
106+++ src/renderers/gl/renderer.cpp 2016-01-19 15:49:22 +0000
107@@ -180,7 +180,10 @@
108 set_rotation(0.0f);
109 }
110
111-mrg::Renderer::~Renderer() = default;
112+mrg::Renderer::~Renderer()
113+{
114+ render_target.ensure_current();
115+}
116
117 void mrg::Renderer::tessellate(std::vector<mgl::Primitive>& primitives,
118 mg::Renderable const& renderable) const
119
120=== modified file 'src/server/input/android/input_sender.cpp'
121--- src/server/input/android/input_sender.cpp 2015-08-20 23:33:42 +0000
122+++ src/server/input/android/input_sender.cpp 2016-01-19 15:49:22 +0000
123@@ -180,16 +180,24 @@
124
125 droidinput::status_t error_status;
126
127- auto event_time = mir_input_event_get_event_time(mir_event_get_input_event(&event.event));
128- if (event.event.type == mir_event_type_key)
129+ auto input_event = mir_event_get_input_event(&event.event);
130+ auto event_time = mir_input_event_get_event_time(input_event);
131+ switch(mir_input_event_get_type(input_event))
132 {
133- error_status = send_key_event(event.sequence_id, event.event.key);
134+ case mir_input_event_type_key:
135+ error_status = send_key_event(event.sequence_id, event.event);
136 state.report->published_key_event(event.channel->server_fd(), event.sequence_id, event_time);
137- }
138- else
139- {
140- error_status = send_motion_event(event.sequence_id, event.event.motion);
141- state.report->published_motion_event(event.channel->server_fd(), event.sequence_id, event_time);
142+ break;
143+ case mir_input_event_type_pointer:
144+ error_status = send_pointer_event(event.sequence_id, event.event);
145+ state.report->published_motion_event(event.channel->server_fd(), event.sequence_id, event_time);
146+ break;
147+ case mir_input_event_type_touch:
148+ error_status = send_touch_event(event.sequence_id, event.event);
149+ state.report->published_motion_event(event.channel->server_fd(), event.sequence_id, event_time);
150+ break;
151+ default:
152+ BOOST_THROW_EXCEPTION(std::runtime_error("unknown input event type"));
153 }
154
155 if (error_status == droidinput::OK)
156@@ -213,6 +221,142 @@
157 }
158 }
159
160+droidinput::status_t mia::InputSender::ActiveTransfer::send_key_event(uint32_t seq, MirEvent const& event)
161+{
162+ int32_t repeat_count = 0;
163+ auto input_event = mir_event_get_input_event(&event);
164+ auto key_event = mir_input_event_get_keyboard_event(input_event);
165+ auto const android_action = mia::android_keyboard_action_from_mir(repeat_count, mir_keyboard_event_action(key_event));
166+ std::chrono::nanoseconds const event_time{mir_input_event_get_event_time(input_event)};
167+ auto const flags = 0;
168+ return publisher.publishKeyEvent(seq,
169+ mir_input_event_get_device_id(input_event),
170+ AINPUT_SOURCE_KEYBOARD,
171+ android_action,
172+ flags,
173+ mir_keyboard_event_key_code(key_event),
174+ mir_keyboard_event_scan_code(key_event),
175+ mia::android_modifiers_from_mir(mir_keyboard_event_modifiers(key_event)),
176+ repeat_count,
177+ event.key.mac,
178+ event_time,
179+ event_time);
180+}
181+
182+droidinput::status_t mia::InputSender::ActiveTransfer::send_touch_event(uint32_t seq, MirEvent const& event)
183+{
184+ droidinput::status_t ret = droidinput::OK;
185+ droidinput::PointerCoords coords[MIR_INPUT_EVENT_MAX_POINTER_COUNT];
186+ droidinput::PointerProperties properties[MIR_INPUT_EVENT_MAX_POINTER_COUNT];
187+ auto input_event = mir_event_get_input_event(&event);
188+ auto touch = mir_input_event_get_touch_event(input_event);
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+
198+ struct StateChange
199+ {
200+ int android_action;
201+ size_t index;
202+ };
203+
204+ std::vector<StateChange> state_changes;
205+ for (size_t i = 0, e = mir_touch_event_point_count(touch); i != e; ++i)
206+ {
207+ auto const action = mir_touch_event_action(touch, i);
208+ if (action == mir_touch_action_down)
209+ state_changes.push_back(StateChange{AMOTION_EVENT_ACTION_DOWN, i});
210+ if (action == mir_touch_action_up)
211+ state_changes.push_back(StateChange{AMOTION_EVENT_ACTION_UP, i});
212+ }
213+
214+ if (state_changes.empty())
215+ state_changes.push_back(StateChange{AMOTION_EVENT_ACTION_MOVE, 0});
216+
217+ for (auto state_change : state_changes)
218+ {
219+ std::memset(&coords, 0, sizeof(coords));
220+ std::memset(&properties, 0, sizeof(properties));
221+
222+ int contacts_in_event = 0;
223+ int action_index = 0;
224+ for (size_t i = 0, e = mir_touch_event_point_count(touch); i != e; ++i)
225+ {
226+ auto const action = mir_touch_event_action(touch, i);
227+
228+ if (i == state_change.index)
229+ action_index = contacts_in_event;
230+
231+ // before a touch up state change got processed it is treated as 'change', skipped otherwise
232+ // after a touch down state change got processed it is treated as 'change', skipped otherwise
233+ if (i == state_change.index
234+ || (i < state_change.index && action != mir_touch_action_up)
235+ || (i > state_change.index && action != mir_touch_action_down))
236+ {
237+ coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_X, mir_touch_event_axis_value(touch, i, mir_touch_axis_x));
238+ coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_Y, mir_touch_event_axis_value(touch, i, mir_touch_axis_y));
239+ coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, mir_touch_event_axis_value(touch, i, mir_touch_axis_touch_major));
240+ coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, mir_touch_event_axis_value(touch, i, mir_touch_axis_touch_minor));
241+ coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_SIZE, mir_touch_event_axis_value(touch, i, mir_touch_axis_size));
242+ coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure));
243+ properties[contacts_in_event].toolType = mia::android_tool_type_from_mir(mir_touch_event_tooltype(touch, i));
244+ properties[contacts_in_event].id = mir_touch_event_id(touch, i);
245+ ++contacts_in_event;
246+ }
247+ }
248+
249+ state_change.android_action |= (action_index << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
250+
251+ ret = publisher.publishMotionEvent(seq, mir_input_event_get_device_id(input_event), AINPUT_SOURCE_TOUCHSCREEN,
252+ state_change.android_action, flags, edge_flags,
253+ mia::android_modifiers_from_mir(mir_touch_event_modifiers(touch)),
254+ button_state, x_offset, y_offset, x_precision, y_precision, event.motion.mac,
255+ event_time, event_time, contacts_in_event, properties, coords);
256+ }
257+
258+ return ret;
259+}
260+
261+droidinput::status_t mia::InputSender::ActiveTransfer::send_pointer_event(uint32_t seq, MirEvent const& event)
262+{
263+ droidinput::PointerCoords pointer_coord;
264+ droidinput::PointerProperties pointer_properties;
265+ std::memset(&pointer_coord, 0, sizeof(pointer_coord));
266+ std::memset(&pointer_properties, 0, sizeof(pointer_properties));
267+
268+ auto input_event = mir_event_get_input_event(&event);
269+ auto pointer = mir_input_event_get_pointer_event(input_event);
270+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_X, mir_pointer_event_axis_value(pointer, mir_pointer_axis_x));
271+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_Y, mir_pointer_event_axis_value(pointer, mir_pointer_axis_y));
272+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll));
273+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll));
274+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_RX, mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_x));
275+ pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_RY, mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_y));
276+ pointer_properties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
277+ pointer_properties.id = 0;
278+
279+ std::chrono::nanoseconds const event_time{mir_input_event_get_event_time(input_event)};
280+ auto const x_offset = 0.0f;
281+ auto const y_offset = 0.0f;
282+ auto const x_precision = 0;
283+ auto const y_precision = 0;
284+ auto const flags = 0;
285+ auto const edge_flags = 0;
286+ return publisher.publishMotionEvent(
287+ seq, mir_input_event_get_device_id(input_event), AINPUT_SOURCE_MOUSE,
288+ mia::android_pointer_action_from_mir(mir_pointer_event_action(pointer), mir_pointer_event_buttons(pointer)),
289+ flags, edge_flags, mia::android_modifiers_from_mir(mir_pointer_event_modifiers(pointer)),
290+ mia::android_pointer_buttons_from_mir(mir_pointer_event_buttons(pointer)), x_offset, y_offset, x_precision,
291+ y_precision, event.motion.mac, event_time, event_time, 1, &pointer_properties, &pointer_coord);
292+}
293+
294+
295+
296 mia::InputSender::ActiveTransfer::~ActiveTransfer()
297 {
298 unsubscribe();
299
300=== modified file 'src/server/input/android/input_sender.h'
301--- src/server/input/android/input_sender.h 2015-08-14 14:51:26 +0000
302+++ src/server/input/android/input_sender.h 2016-01-19 15:49:22 +0000
303@@ -97,6 +97,10 @@
304
305 private:
306 void on_finish_signal();
307+ droidinput::status_t send_key_event(uint32_t sequence_id, MirEvent const& event);
308+ droidinput::status_t send_touch_event(uint32_t sequence_id, MirEvent const& event);
309+ droidinput::status_t send_pointer_event(uint32_t sequence_id, MirEvent const& event);
310+
311 void on_response_timeout();
312 void update_timer();
313 void cancel_timer();
314
315=== modified file 'tests/unit-tests/graphics/mesa/kms/test_platform.cpp'
316--- tests/unit-tests/graphics/mesa/kms/test_platform.cpp 2015-12-16 13:01:56 +0000
317+++ tests/unit-tests/graphics/mesa/kms/test_platform.cpp 2016-01-19 15:49:22 +0000
318@@ -332,6 +332,26 @@
319 EXPECT_EQ(mg::PlatformPriority::best, probe(options));
320 }
321
322+TEST_F(MesaGraphicsPlatform, probe_returns_in_between_when_cant_set_master)
323+{ // Regression test for LP: #1528082
324+ using namespace testing;
325+
326+ mtf::UdevEnvironment udev_environment;
327+ boost::program_options::options_description po;
328+ mir::options::ProgramOption options;
329+
330+ udev_environment.add_standard_device("standard-drm-devices");
331+
332+ EXPECT_CALL(mock_drm, drmSetMaster(_))
333+ .WillOnce(Return(-1));
334+
335+ mir::SharedLibrary platform_lib{mtf::server_platform("graphics-mesa-kms")};
336+ auto probe = platform_lib.load_function<mg::PlatformProbe>(probe_platform);
337+ auto prio = probe(options);
338+ EXPECT_THAT(prio, Gt(mg::PlatformPriority::unsupported));
339+ EXPECT_THAT(prio, Lt(mg::PlatformPriority::supported));
340+}
341+
342 TEST_F(MesaGraphicsPlatform, probe_returns_best_when_drm_devices_vt_option_exist)
343 {
344 mtf::UdevEnvironment udev_environment;
345
346=== modified file 'tests/unit-tests/input/android/test_android_input_sender.cpp'
347--- tests/unit-tests/input/android/test_android_input_sender.cpp 2015-08-13 21:44:58 +0000
348+++ tests/unit-tests/input/android/test_android_input_sender.cpp 2016-01-19 15:49:22 +0000
349@@ -22,6 +22,7 @@
350 #include "src/server/input/android/android_input_channel.h"
351 #include "src/server/input/android/input_sender.h"
352 #include "src/server/report/null_report_factory.h"
353+#include "src/server/input/default_event_builder.h"
354
355 #include "mir/test/doubles/stub_scene_surface.h"
356 #include "mir/test/doubles/mock_input_surface.h"
357@@ -36,6 +37,7 @@
358 #include "androidfw/InputTransport.h"
359
360 #include "mir/input/input_report.h"
361+#include "mir/cookie_factory.h"
362
363 #include <gtest/gtest.h>
364 #include <gmock/gmock.h>
365@@ -92,6 +94,14 @@
366 std::shared_ptr<ms::Observer> observer;
367 };
368
369+class StubCookieFactory : public mir::cookie::CookieFactory
370+{
371+public:
372+ MirCookie timestamp_to_cookie(uint64_t const&) override { return {0, 0};}
373+ bool attest_timestamp(MirCookie const&) override {return true;}
374+ StubCookieFactory() = default;
375+};
376+
377 }
378
379 class AndroidInputSender : public ::testing::Test
380@@ -101,7 +111,14 @@
381 size_t const test_pointer_count = 2;
382 float test_x_coord[2] = {12, 23};
383 float test_y_coord[2] = {17, 9};
384-
385+ MirTouchTooltype const tool = mir_touch_tooltype_finger;
386+ float const pressure = 0.6f;
387+ float const major = 8;
388+ float const minor = 4;
389+ float const size = 8;
390+ StubCookieFactory cookie_factory;
391+ mi::DefaultEventBuilder builder{MirInputDeviceId(), mt::fake_shared(cookie_factory)};
392+
393 AndroidInputSender()
394 : key_event(mev::make_event(MirInputDeviceId(), std::chrono::nanoseconds(1), 0, mir_keyboard_action_down,
395 7, test_scan_code, mir_input_event_modifier_none)),
396@@ -394,3 +411,150 @@
397 ::close(channel->client_fd());
398 sender.send_event(*key_event, channel);
399 }
400+
401+TEST_F(AndroidInputSender, encodes_multiple_touch_contact_downs_as_multiple_events)
402+{
403+ // TODO When the rework of the transport encoding is finished we might want to revisit this decision
404+ register_surface();
405+
406+ auto touch_ev_with_simultaneous_down = builder.touch_event(std::chrono::nanoseconds(86));
407+ builder.add_touch(*touch_ev_with_simultaneous_down, 2, mir_touch_action_down, tool, 50, 60, pressure, major, minor, size);
408+ builder.add_touch(*touch_ev_with_simultaneous_down, 4, mir_touch_action_down, tool, 80, 90, pressure, major, minor, size);
409+
410+ sender.send_event(*touch_ev_with_simultaneous_down, channel);
411+
412+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
413+ EXPECT_EQ(&client_motion_event, event);
414+ EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, client_motion_event.getActionMasked());
415+ EXPECT_EQ(0, client_motion_event.getActionIndex());
416+ EXPECT_EQ(2, client_motion_event.getPointerId(0));
417+ EXPECT_EQ(1, client_motion_event.getPointerCount());
418+
419+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
420+ EXPECT_EQ(&client_motion_event, event);
421+ EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, client_motion_event.getActionMasked());
422+ EXPECT_EQ(1, client_motion_event.getActionIndex());
423+ EXPECT_EQ(2, client_motion_event.getPointerId(0));
424+ EXPECT_EQ(4, client_motion_event.getPointerId(1));
425+ EXPECT_EQ(2, client_motion_event.getPointerCount());
426+}
427+
428+TEST_F(AndroidInputSender, encodes_multiple_touch_contact_downs_as_multiple_events_but_keeps_only_moved_contacts_in_place)
429+{
430+ // TODO When the rework of the transport encoding is finished we might want to revisit this decision
431+ register_surface();
432+
433+ auto touch_ev_with_simultaneous_down = builder.touch_event(std::chrono::nanoseconds(86));
434+ builder.add_touch(*touch_ev_with_simultaneous_down, 2, mir_touch_action_down, tool, 50, 60, pressure, major, minor, size);
435+ builder.add_touch(*touch_ev_with_simultaneous_down, 3, mir_touch_action_change, tool, 10, 10, pressure, major, minor, size);
436+ builder.add_touch(*touch_ev_with_simultaneous_down, 4, mir_touch_action_down, tool, 80, 90, pressure, major, minor, size);
437+
438+ sender.send_event(*touch_ev_with_simultaneous_down, channel);
439+
440+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
441+ EXPECT_EQ(&client_motion_event, event);
442+ EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, client_motion_event.getActionMasked());
443+ EXPECT_EQ(0, client_motion_event.getActionIndex());
444+ EXPECT_EQ(2, client_motion_event.getPointerId(0));
445+ EXPECT_EQ(3, client_motion_event.getPointerId(1));
446+ EXPECT_EQ(2, client_motion_event.getPointerCount());
447+
448+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
449+ EXPECT_EQ(&client_motion_event, event);
450+ EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, client_motion_event.getActionMasked());
451+ EXPECT_EQ(2, client_motion_event.getActionIndex());
452+ EXPECT_EQ(2, client_motion_event.getPointerId(0));
453+ EXPECT_EQ(3, client_motion_event.getPointerId(1));
454+ EXPECT_EQ(4, client_motion_event.getPointerId(2));
455+ EXPECT_EQ(3, client_motion_event.getPointerCount());
456+}
457+
458+TEST_F(AndroidInputSender, encodes_multiple_releases_in_several_events)
459+{
460+ // TODO When the rework of the transport encoding is finished we might want to revisit this decision
461+ register_surface();
462+
463+ auto touch_ev_with_simultaneous_down = builder.touch_event(std::chrono::nanoseconds(86));
464+ builder.add_touch(*touch_ev_with_simultaneous_down, 2, mir_touch_action_up, tool, 50, 60, pressure, major, minor, size);
465+ builder.add_touch(*touch_ev_with_simultaneous_down, 3, mir_touch_action_change, tool, 10, 10, pressure, major, minor, size);
466+ builder.add_touch(*touch_ev_with_simultaneous_down, 4, mir_touch_action_up, tool, 80, 90, pressure, major, minor, size);
467+
468+ sender.send_event(*touch_ev_with_simultaneous_down, channel);
469+
470+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
471+ EXPECT_EQ(&client_motion_event, event);
472+ EXPECT_EQ(AMOTION_EVENT_ACTION_UP, client_motion_event.getActionMasked());
473+ EXPECT_EQ(0, client_motion_event.getActionIndex());
474+ EXPECT_EQ(2, client_motion_event.getPointerId(0));
475+ EXPECT_EQ(3, client_motion_event.getPointerId(1));
476+ EXPECT_EQ(4, client_motion_event.getPointerId(2));
477+ EXPECT_EQ(3, client_motion_event.getPointerCount());
478+
479+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
480+ EXPECT_EQ(&client_motion_event, event);
481+ EXPECT_EQ(AMOTION_EVENT_ACTION_UP, client_motion_event.getActionMasked());
482+ EXPECT_EQ(1, client_motion_event.getActionIndex());
483+ EXPECT_EQ(3, client_motion_event.getPointerId(0));
484+ EXPECT_EQ(4, client_motion_event.getPointerId(1));
485+ EXPECT_EQ(2, client_motion_event.getPointerCount());
486+}
487+
488+TEST_F(AndroidInputSender, encodes_combinations_of_up_and_down_one_by_one)
489+{
490+ // TODO When the rework of the transport encoding is finished we might want to revisit this decision
491+ register_surface();
492+
493+ auto touch_ev_with_simultaneous_down = builder.touch_event(std::chrono::nanoseconds(86));
494+ builder.add_touch(*touch_ev_with_simultaneous_down, 2, mir_touch_action_up, tool, 50, 60, pressure, major, minor, size);
495+ builder.add_touch(*touch_ev_with_simultaneous_down, 3, mir_touch_action_change, tool, 10, 10, pressure, major, minor, size);
496+ builder.add_touch(*touch_ev_with_simultaneous_down, 4, mir_touch_action_down, tool, 80, 90, pressure, major, minor, size);
497+
498+ sender.send_event(*touch_ev_with_simultaneous_down, channel);
499+
500+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
501+ EXPECT_EQ(&client_motion_event, event);
502+ EXPECT_EQ(AMOTION_EVENT_ACTION_UP, client_motion_event.getActionMasked());
503+ EXPECT_EQ(0, client_motion_event.getActionIndex());
504+ EXPECT_EQ(2, client_motion_event.getPointerId(0));
505+ EXPECT_EQ(3, client_motion_event.getPointerId(1));
506+ EXPECT_EQ(2, client_motion_event.getPointerCount());
507+
508+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
509+ EXPECT_EQ(&client_motion_event, event);
510+ EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, client_motion_event.getActionMasked());
511+ EXPECT_EQ(1, client_motion_event.getActionIndex());
512+ EXPECT_EQ(3, client_motion_event.getPointerId(0));
513+ EXPECT_EQ(4, client_motion_event.getPointerId(1));
514+ EXPECT_EQ(2, client_motion_event.getPointerCount());
515+}
516+
517+TEST_F(AndroidInputSender, encodes_combinations_of_down_and_up_one_by_one)
518+{
519+ // TODO When the rework of the transport encoding is finished we might want to revisit this decision
520+ register_surface();
521+
522+ auto touch_ev_with_simultaneous_down = builder.touch_event(std::chrono::nanoseconds(86));
523+ builder.add_touch(*touch_ev_with_simultaneous_down, 2, mir_touch_action_down, tool, 50, 60, pressure, major, minor, size);
524+ builder.add_touch(*touch_ev_with_simultaneous_down, 3, mir_touch_action_change, tool, 10, 10, pressure, major, minor, size);
525+ builder.add_touch(*touch_ev_with_simultaneous_down, 4, mir_touch_action_up, tool, 80, 90, pressure, major, minor, size);
526+
527+ sender.send_event(*touch_ev_with_simultaneous_down, channel);
528+
529+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
530+ EXPECT_EQ(&client_motion_event, event);
531+ EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, client_motion_event.getActionMasked());
532+ EXPECT_EQ(0, client_motion_event.getActionIndex());
533+ EXPECT_EQ(2, client_motion_event.getPointerId(0));
534+ EXPECT_EQ(3, client_motion_event.getPointerId(1));
535+ EXPECT_EQ(4, client_motion_event.getPointerId(2));
536+ EXPECT_EQ(3, client_motion_event.getPointerCount());
537+
538+ EXPECT_EQ(droidinput::OK, consumer.consume(&event_factory, true, std::chrono::nanoseconds(86), &seq, &event));
539+ EXPECT_EQ(&client_motion_event, event);
540+ EXPECT_EQ(AMOTION_EVENT_ACTION_UP, client_motion_event.getActionMasked());
541+ EXPECT_EQ(2, client_motion_event.getActionIndex());
542+ EXPECT_EQ(2, client_motion_event.getPointerId(0));
543+ EXPECT_EQ(3, client_motion_event.getPointerId(1));
544+ EXPECT_EQ(4, client_motion_event.getPointerId(2));
545+ EXPECT_EQ(3, client_motion_event.getPointerCount());
546+}
547
548=== modified file 'tests/unit-tests/renderers/gl/CMakeLists.txt'
549--- tests/unit-tests/renderers/gl/CMakeLists.txt 2015-09-07 11:54:56 +0000
550+++ tests/unit-tests/renderers/gl/CMakeLists.txt 2016-01-19 15:49:22 +0000
551@@ -1,5 +1,4 @@
552 list(APPEND UNIT_TEST_SOURCES
553- ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_program_family.cpp
554 ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_renderer.cpp
555 )
556
557
558=== removed file 'tests/unit-tests/renderers/gl/test_gl_program_family.cpp'
559--- tests/unit-tests/renderers/gl/test_gl_program_family.cpp 2015-09-11 12:29:40 +0000
560+++ tests/unit-tests/renderers/gl/test_gl_program_family.cpp 1970-01-01 00:00:00 +0000
561@@ -1,49 +0,0 @@
562-/*
563- * Copyright © 2015 Canonical Ltd.
564- *
565- * This program is free software: you can redistribute it and/or modify
566- * it under the terms of the GNU General Public License version 3 as
567- * published by the Free Software Foundation.
568- *
569- * This program is distributed in the hope that it will be useful,
570- * but WITHOUT ANY WARRANTY; without even the implied warranty of
571- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
572- * GNU General Public License for more details.
573- *
574- * You should have received a copy of the GNU General Public License
575- * along with this program. If not, see <http://www.gnu.org/licenses/>.
576- *
577- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
578- */
579-
580-#include "src/renderers/gl/program_family.h"
581-#include "mir/test/doubles/mock_gl.h"
582-#include "mir/test/doubles/mock_egl.h"
583-
584-#include <gtest/gtest.h>
585-#include <gmock/gmock.h>
586-
587-namespace mtd = mir::test::doubles;
588-namespace mrg = mir::renderer::gl;
589-
590-// Regression test for LP: #1454201
591-TEST(GLProgramFamily, releases_gl_context_before_deleting_shader_objects)
592-{
593- using namespace testing;
594-
595- NiceMock<mtd::MockGL> mock_gl;
596- NiceMock<mtd::MockEGL> mock_egl;
597-
598- ON_CALL(mock_gl, glCreateShader(_)).WillByDefault(Return(1));
599- ON_CALL(mock_gl, glCreateProgram()).WillByDefault(Return(1));
600-
601- {
602- mrg::ProgramFamily family;
603- family.add_program("vertex shader", "fragment shader");
604-
605- InSequence seq;
606- EXPECT_CALL(mock_egl, eglMakeCurrent(_,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT));
607- EXPECT_CALL(mock_gl, glDeleteProgram(_)).Times(1);
608- EXPECT_CALL(mock_gl, glDeleteShader(_)).Times(2);
609- }
610-}
611
612=== modified file 'tests/unit-tests/renderers/gl/test_gl_renderer.cpp'
613--- tests/unit-tests/renderers/gl/test_gl_renderer.cpp 2015-10-26 12:25:02 +0000
614+++ tests/unit-tests/renderers/gl/test_gl_renderer.cpp 2016-01-19 15:49:22 +0000
615@@ -265,6 +265,8 @@
616 EXPECT_CALL(mock_display_buffer, make_current());
617
618 mrg::Renderer renderer(mock_display_buffer);
619+
620+ testing::Mock::VerifyAndClearExpectations(&mock_display_buffer);
621 }
622
623 TEST_F(GLRenderer, releases_display_buffer_current_when_destroyed)
624@@ -274,6 +276,21 @@
625 EXPECT_CALL(mock_display_buffer, release_current());
626 }
627
628+TEST_F(GLRenderer, makes_display_buffer_current_before_deleting_programs)
629+{
630+ mrg::Renderer renderer(mock_display_buffer);
631+
632+ InSequence seq;
633+ EXPECT_CALL(mock_display_buffer, make_current());
634+ EXPECT_CALL(mock_display_buffer, swap_buffers());
635+ EXPECT_CALL(mock_display_buffer, make_current());
636+ EXPECT_CALL(mock_gl, glDeleteProgram(_)).Times(AtLeast(1));
637+ EXPECT_CALL(mock_gl, glDeleteShader(_)).Times(AtLeast(1));
638+ EXPECT_CALL(mock_display_buffer, release_current());
639+
640+ renderer.render(renderable_list);
641+}
642+
643 TEST_F(GLRenderer, makes_display_buffer_current_before_rendering)
644 {
645 mrg::Renderer renderer(mock_display_buffer);
646@@ -283,6 +300,8 @@
647 EXPECT_CALL(mock_gl, glClear(_));
648
649 renderer.render(renderable_list);
650+
651+ testing::Mock::VerifyAndClearExpectations(&mock_display_buffer);
652 }
653
654 TEST_F(GLRenderer, swaps_buffers_after_rendering)

Subscribers

People subscribed via source and target branches

to all changes: