Mir

Merge lp:~andreas-pokorny/mir/fix-1539009-proper-accumulation-of-batched-events into lp:mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Cemil Azizoglu
Approved revision: no longer in the source branch.
Merged at revision: 3330
Proposed branch: lp:~andreas-pokorny/mir/fix-1539009-proper-accumulation-of-batched-events
Merge into: lp:mir
Diff against target: 316 lines (+273/-2)
4 files modified
3rd_party/android-input/android/frameworks/base/include/androidfw/Input.h (+1/-0)
3rd_party/android-input/android/frameworks/base/services/input/Input.cpp (+19/-2)
tests/unit-tests/input/android/CMakeLists.txt (+1/-0)
tests/unit-tests/input/android/test_input_consumer.cpp (+252/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/fix-1539009-proper-accumulation-of-batched-events
Reviewer Review Type Date Requested Status
Cemil Azizoglu (community) Approve
Alan Griffiths Approve
Daniel van Vugt Approve
PS Jenkins bot (community) continuous-integration Approve
Mir CI Bot continuous-integration Approve
Review via email: mp+286697@code.launchpad.net

Commit message

Fix relative axis in motion events

scroll and relative movement are axis that have to be accumulated when notified in batches. InputConsumer batches those when the consume rate is a lower and somewhat delayed compared to the arrival of the events. The given change does not fix InputConsumer but adds code in MotionEvent to accumulate the relevant axis values as needed.

(LP: #1539009)

Description of the change

Not quite the MP I hoped this to be.. But at least we have a starting point of features the InputConsumer should support. The code is horribly convoluted..

So as soon as we know what InputConsumer is supposed to do we can start replacing it..

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) 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
Mir CI Bot (mir-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Coooool.

Is this a full or partial fix for bug 1539009 then?

review: Needs Information
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 :

I'm not sure this is working. MIR_CLIENT_INPUT_RECEIVER_REPORT=log should show dx mostly agreeing with the change in absolute x. But what I see is still a large discrepancy:

BEFORE:

[2016-02-22 18:20:29.458772] <DEBUG> input-receiver: Received event:pointer_event(when=160587554000 (6.085664ms ago), from=6, motion, button_state=0, x=98, y=280, dx=3, dy=0, vscroll=0, hscroll=0, modifiers=1)

[2016-02-22 18:20:29.475780] <DEBUG> input-receiver: Received event:pointer_event(when=160604556000 (6.092153ms ago), from=6, motion, button_state=0, x=118, y=278, dx=3, dy=0, vscroll=0, hscroll=0, modifiers=1)

[2016-02-22 18:20:29.492779] <DEBUG> input-receiver: Received event:pointer_event(when=160621554000 (6.093218ms ago), from=6, motion, button_state=0, x=136, y=277, dx=3, dy=0, vscroll=0, hscroll=0, modifiers=1)

[2016-02-22 18:20:29.509860] <DEBUG> input-receiver: Received event:pointer_event(when=160638553000 (6.173124ms ago), from=6, motion, button_state=0, x=148, y=276, dx=1, dy=-1, vscroll=0, hscroll=0, modifiers=1)

[2016-02-22 18:20:29.526800] <DEBUG> input-receiver: Received event:pointer_event(when=160654555000 (7.112560ms ago), from=6, motion, button_state=0, x=159, y=276, dx=2, dy=0, vscroll=0, hscroll=0, modifiers=1)

AFTER:

[2016-02-22 18:21:18.085902] <DEBUG> input-receiver: Received event:pointer_event(when=209214636000 (6.131677ms ago), from=6, motion, button_state=0, x=115, y=171, dx=4, dy=0, vscroll=0, hscroll=0, modifiers=1)

[2016-02-22 18:21:18.102987] <DEBUG> input-receiver: Received event:pointer_event(when=209231631000 (6.222729ms ago), from=6, motion, button_state=0, x=187, y=171, dx=4, dy=0, vscroll=0, hscroll=0, modifiers=1)

[2016-02-22 18:21:18.119989] <DEBUG> input-receiver: Received event:pointer_event(when=209248633000 (6.222841ms ago), from=6, motion, button_state=0, x=259, y=165, dx=4, dy=-2, vscroll=0, hscroll=0, modifiers=1)

[2016-02-22 18:21:18.136985] <DEBUG> input-receiver: Received event:pointer_event(when=209265631000 (6.220547ms ago), from=6, motion, button_state=0, x=315, y=161, dx=2, dy=0, vscroll=0, hscroll=0, modifiers=1)

[2016-02-22 18:21:18.153992] <DEBUG> input-receiver: Received event:pointer_event(when=209282580000 (6.273110ms ago), from=6, motion, button_state=0, x=340, y=155, dx=1, dy=0, vscroll=0, hscroll=0, modifiers=1)

[2016-02-22 18:21:18.170721] <DEBUG> input-receiver: Received event:pointer_event(when=209295634000 (9.946535ms ago), from=6, motion, button_state=0, x=345, y=152, dx=1, dy=-1, vscroll=0, hscroll=0, modifiers=1)

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

> Coooool.
>
> Is this a full or partial fix for bug 1539009 then?

uh it should solve the test case :).. I have to look how the trace is generated .. there are two paths to access axis I believe I only fixed one of them..

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

> I'm not sure this is working. MIR_CLIENT_INPUT_RECEIVER_REPORT=log should show
> dx mostly agreeing with the change in absolute x. But what I see is still a
> large discrepancy:
>
> BEFORE:
>
> [2016-02-22 18:20:29.458772] <DEBUG> input-receiver: Received
> event:pointer_event(when=160587554000 (6.085664ms ago), from=6, motion,
> button_state=0, x=98, y=280, dx=3, dy=0, vscroll=0, hscroll=0, modifiers=1)
>
> [2016-02-22 18:20:29.475780] <DEBUG> input-receiver: Received
> event:pointer_event(when=160604556000 (6.092153ms ago), from=6, motion,
> button_state=0, x=118, y=278, dx=3, dy=0, vscroll=0, hscroll=0, modifiers=1)
>
> [2016-02-22 18:20:29.492779] <DEBUG> input-receiver: Received
> event:pointer_event(when=160621554000 (6.093218ms ago), from=6, motion,
> button_state=0, x=136, y=277, dx=3, dy=0, vscroll=0, hscroll=0, modifiers=1)
>
> [2016-02-22 18:20:29.509860] <DEBUG> input-receiver: Received
> event:pointer_event(when=160638553000 (6.173124ms ago), from=6, motion,
> button_state=0, x=148, y=276, dx=1, dy=-1, vscroll=0, hscroll=0, modifiers=1)
>
> [2016-02-22 18:20:29.526800] <DEBUG> input-receiver: Received
> event:pointer_event(when=160654555000 (7.112560ms ago), from=6, motion,
> button_state=0, x=159, y=276, dx=2, dy=0, vscroll=0, hscroll=0, modifiers=1)
>
>
> AFTER:
>
> [2016-02-22 18:21:18.085902] <DEBUG> input-receiver: Received
> event:pointer_event(when=209214636000 (6.131677ms ago), from=6, motion,
> button_state=0, x=115, y=171, dx=4, dy=0, vscroll=0, hscroll=0, modifiers=1)
>
> [2016-02-22 18:21:18.102987] <DEBUG> input-receiver: Received
> event:pointer_event(when=209231631000 (6.222729ms ago), from=6, motion,
> button_state=0, x=187, y=171, dx=4, dy=0, vscroll=0, hscroll=0, modifiers=1)
>
> [2016-02-22 18:21:18.119989] <DEBUG> input-receiver: Received
> event:pointer_event(when=209248633000 (6.222841ms ago), from=6, motion,
> button_state=0, x=259, y=165, dx=4, dy=-2, vscroll=0, hscroll=0, modifiers=1)
>
> [2016-02-22 18:21:18.136985] <DEBUG> input-receiver: Received
> event:pointer_event(when=209265631000 (6.220547ms ago), from=6, motion,
> button_state=0, x=315, y=161, dx=2, dy=0, vscroll=0, hscroll=0, modifiers=1)
>
> [2016-02-22 18:21:18.153992] <DEBUG> input-receiver: Received
> event:pointer_event(when=209282580000 (6.273110ms ago), from=6, motion,
> button_state=0, x=340, y=155, dx=1, dy=0, vscroll=0, hscroll=0, modifiers=1)
>
> [2016-02-22 18:21:18.170721] <DEBUG> input-receiver: Received
> event:pointer_event(when=209295634000 (9.946535ms ago), from=6, motion,
> button_state=0, x=345, y=152, dx=1, dy=-1, vscroll=0, hscroll=0, modifiers=1)

Yes should be fixed now..

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3312
https://mir-jenkins.ubuntu.com/job/mir-ci/352/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/144
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/157
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/153
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/153
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/149
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/149/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/149
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/149/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/149
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/149/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/149
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/149/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/352/rebuild

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

PASSED: Continuous integration, rev:3312
http://jenkins.qa.ubuntu.com/job/mir-ci/6342/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5993
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4900
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5949
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/466
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/666
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/666/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/666
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/666/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5946
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5946/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8320
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27793
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/462
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/462/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/315
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27797

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

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

Approved: I have now verified the fix works, using manual test case:
https://bugs.launchpad.net/mir/+bug/1539009/comments/8

It also seems my previous concern might have been a mistake in the way I tested it yesterday.

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

Without the fix:

[1456212286.328351] <DEBUG> input-receiver: Received event:pointer_event(when=17346454506000 (0.229968ms ago), from=6, enter, button_state=0, x=3, y=213, dx=9, dy=1, vscroll=0, hscroll=0, modifiers=1)

[1456212286.348252] <DEBUG> input-receiver: Received event:pointer_event(when=17346468512000 (6.119945ms ago), from=6, motion, button_state=0, x=128, y=221, dx=10, dy=0, vscroll=0, hscroll=0, modifiers=1)

[1456212286.365179] <DEBUG> input-receiver: Received event:pointer_event(when=17346485512000 (6.047213ms ago), from=6, motion, button_state=0, x=293, y=223, dx=11, dy=0, vscroll=0, hscroll=0, modifiers=1)

[1456212286.381260] <DEBUG> input-receiver: Received event:pointer_event(when=17346506476000 (1.171607ms ago), from=6, motion, button_state=0, x=501, y=212, dx=10, dy=-1, vscroll=0, hscroll=0, modifiers=1)

[1456212286.381314] <DEBUG> input-receiver: Received event:pointer_event(when=17346507451000 (0.251745ms ago), from=6, leave, button_state=0, x=512, y=212, dx=11, dy=0, vscroll=0, hscroll=0, modifiers=1)

--------
With the fix:

[2016-02-23 15:25:59.513071] <DEBUG> input-receiver: Received event:pointer_event(when=17419639254000 (0.202009ms ago), from=6, enter, button_state=0, x=0, y=182, dx=8, dy=0, vscroll=0, hscroll=0, modifiers=1)

[2016-02-23 15:25:59.534141] <DEBUG> input-receiver: Received event:pointer_event(when=17419655249000 (5.275370ms ago), from=6, motion, button_state=0, x=138, y=195, dx=146, dy=13, vscroll=0, hscroll=0, modifiers=1)

[2016-02-23 15:25:59.551953] <DEBUG> input-receiver: Received event:pointer_event(when=17419672219000 (6.118942ms ago), from=6, motion, button_state=0, x=302, y=206, dx=164, dy=11, vscroll=0, hscroll=0, modifiers=1)

[2016-02-23 15:25:59.568163] <DEBUG> input-receiver: Received event:pointer_event(when=17419689296000 (5.250705ms ago), from=6, motion, button_state=0, x=470, y=208, dx=168, dy=2, vscroll=0, hscroll=0, modifiers=1)

[2016-02-23 15:25:59.568234] <DEBUG> input-receiver: Received event:pointer_event(when=17419693301000 (1.327157ms ago), from=6, motion, button_state=0, x=508, y=206, dx=38, dy=-2, vscroll=0, hscroll=0, modifiers=1)

[2016-02-23 15:25:59.568261] <DEBUG> input-receiver: Received event:pointer_event(when=17419694296000 (0.360347ms ago), from=6, leave, button_state=0, x=518, y=206, dx=10, dy=0, vscroll=0, hscroll=0, modifiers=1)

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

Looks reasonable, and Daniel's tested the bug is fixed.

review: Approve
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '3rd_party/android-input/android/frameworks/base/include/androidfw/Input.h'
--- 3rd_party/android-input/android/frameworks/base/include/androidfw/Input.h 2016-01-29 08:18:22 +0000
+++ 3rd_party/android-input/android/frameworks/base/include/androidfw/Input.h 2016-02-22 14:07:25 +0000
@@ -554,6 +554,7 @@
554 }554 }
555555
556protected:556protected:
557 float getAccumulatedAxisValue(int32_t axis, size_t pointerIndex) const;
557 int32_t mAction;558 int32_t mAction;
558 int32_t mFlags;559 int32_t mFlags;
559 int32_t mEdgeFlags;560 int32_t mEdgeFlags;
560561
=== modified file '3rd_party/android-input/android/frameworks/base/services/input/Input.cpp'
--- 3rd_party/android-input/android/frameworks/base/services/input/Input.cpp 2016-01-29 08:18:22 +0000
+++ 3rd_party/android-input/android/frameworks/base/services/input/Input.cpp 2016-02-22 14:07:25 +0000
@@ -359,12 +359,29 @@
359 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];359 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
360}360}
361361
362float MotionEvent::getAccumulatedAxisValue(int32_t axis, size_t pointerIndex) const {
363 float acc = 0;
364 auto const pointerCount = getPointerCount();
365 for (size_t i = 0, num_entries = getHistorySize() + 1; i != num_entries; ++i)
366 acc += mSamplePointerCoords[i * pointerCount + pointerIndex].getAxisValue(axis);
367 return acc;
368}
369
362float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {370float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
363 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);371 switch (axis)
372 {
373 case AMOTION_EVENT_AXIS_RX: // joystick rotation axis are abused as relative x and y
374 case AMOTION_EVENT_AXIS_RY:
375 case AMOTION_EVENT_AXIS_VSCROLL:
376 case AMOTION_EVENT_AXIS_HSCROLL:
377 return getAccumulatedAxisValue(axis, pointerIndex);
378 default:
379 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
380 }
364}381}
365382
366float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {383float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
367 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);384 float value = getRawAxisValue(axis, pointerIndex);
368 switch (axis) {385 switch (axis) {
369 case AMOTION_EVENT_AXIS_X:386 case AMOTION_EVENT_AXIS_X:
370 return value + mXOffset;387 return value + mXOffset;
371388
=== modified file 'tests/unit-tests/input/android/CMakeLists.txt'
--- tests/unit-tests/input/android/CMakeLists.txt 2016-01-29 08:18:22 +0000
+++ tests/unit-tests/input/android/CMakeLists.txt 2016-02-22 14:07:25 +0000
@@ -3,6 +3,7 @@
3 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_channel_factory.cpp3 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_channel_factory.cpp
4 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_communication_package.cpp4 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_communication_package.cpp
5 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_sender.cpp5 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_input_sender.cpp
6 ${CMAKE_CURRENT_SOURCE_DIR}/test_input_consumer.cpp
6)7)
78
8set(9set(
910
=== added file 'tests/unit-tests/input/android/test_input_consumer.cpp'
--- tests/unit-tests/input/android/test_input_consumer.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/input/android/test_input_consumer.cpp 2016-02-22 14:07:25 +0000
@@ -0,0 +1,252 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
17 */
18
19#include "androidfw/Input.h"
20#include "androidfw/InputTransport.h"
21#include "src/server/input/android/android_input_channel.h"
22#include "mir/input/android/event_conversion_helpers.h"
23#include "mir/input/android/android_input_lexicon.h"
24#include "mir/geometry/displacement.h"
25#include "mir/geometry/point.h"
26
27#include <gtest/gtest.h>
28#include <chrono>
29#include <vector>
30#include <cstring>
31
32using namespace std::literals::chrono_literals;
33namespace mia = mir::input::android;
34namespace geom = mir::geometry;
35
36namespace
37{
38struct EventFactory : android::InputEventFactoryInterface
39{
40 android::KeyEvent key;
41 android::MotionEvent motion;
42 android::KeyEvent* createKeyEvent()
43 {
44 return &key;
45 }
46 android::MotionEvent* createMotionEvent()
47 {
48 return &motion;
49 }
50};
51}
52
53struct InputConsumerTest : ::testing::Test
54{
55 MOCK_METHOD3(pointer_movement,void(geom::Point pos, geom::Displacement movement, geom::Displacement scroll));
56 uint32_t seq{0};
57 mir::cookie::Blob default_cookie;
58 EventFactory events;
59 std::chrono::milliseconds current_frame_time = 0ms;
60 mia::AndroidInputChannel channel;
61 geom::Displacement no_move{0,0};
62 geom::Displacement no_scroll{0,0};
63 geom::Point origin{0,0};
64 droidinput::sp<droidinput::InputChannel> client_channel =
65 new droidinput::InputChannel("test_client", channel.client_fd());
66 droidinput::sp<droidinput::InputChannel> server_channel =
67 new droidinput::InputChannel("test_server", channel.server_fd());
68
69 droidinput::InputPublisher publisher{server_channel};
70 droidinput::InputConsumer consumer{client_channel};
71
72 InputConsumerTest()
73 {
74 std::memset(&default_cookie, 0, sizeof default_cookie);
75 }
76
77 const MirInputDeviceId touchscreen_device = 2;
78 const MirInputDeviceId mouse_device = 3;
79 struct TouchEvent
80 {
81 int action; // only one action per event - android InputTransport restriction
82 std::vector<geom::Point> positions;
83 std::chrono::nanoseconds tp;
84 };
85 void send_touch_event(TouchEvent const& event)
86 {
87 std::vector<droidinput::PointerCoords> coords(event.positions.size());
88 std::vector<droidinput::PointerProperties> properties(event.positions.size());
89 std::memset(coords.data(), 0, sizeof coords[0] * coords.size());
90 std::memset(properties.data(), 0, sizeof properties[0] * properties.size());
91 auto const x_offset = 0.0f;
92 auto const y_offset = 0.0f;
93 auto const x_precision = 0;
94 auto const y_precision = 0;
95 auto const flags = 0;
96 auto const edge_flags = 0;
97 auto const button_state = 0;
98 int contacts_in_event = 0;
99 for (auto const& contact : event.positions)
100 {
101 coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_X, contact.x.as_float());
102 coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_Y, contact.y.as_float());
103 coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 5);
104 coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 5);
105 coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 5);
106 coords[contacts_in_event].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.7);
107 properties[contacts_in_event].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
108 properties[contacts_in_event].id = contacts_in_event;
109 }
110
111 publisher.publishMotionEvent(++seq, touchscreen_device, AINPUT_SOURCE_TOUCHSCREEN, event.action, flags,
112 edge_flags, 0, button_state, x_offset, y_offset, x_precision, y_precision,
113 default_cookie, event.tp, event.tp, contacts_in_event, properties.data(),
114 coords.data());
115 }
116
117 struct PointerEvent
118 {
119 MirPointerAction action;
120 MirPointerButtons buttons;
121 geom::Point position;
122 geom::Displacement movement;
123 geom::Displacement scroll;
124 std::chrono::nanoseconds tp;
125 };
126 void send_pointer_event(PointerEvent const& event)
127 {
128 droidinput::PointerCoords pointer_coord;
129 droidinput::PointerProperties pointer_properties;
130 std::memset(&pointer_coord, 0, sizeof(pointer_coord));
131 std::memset(&pointer_properties, 0, sizeof(pointer_properties));
132
133 pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_X, event.position.x.as_float());
134 pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_Y, event.position.y.as_float());
135 pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, event.scroll.dx.as_float());
136 pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, event.scroll.dy.as_float());
137 pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_RX, event.movement.dx.as_float());
138 pointer_coord.setAxisValue(AMOTION_EVENT_AXIS_RY, event.movement.dy.as_float());
139 pointer_properties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
140 pointer_properties.id = 0;
141
142 auto const x_offset = 0.0f;
143 auto const y_offset = 0.0f;
144 auto const x_precision = 0;
145 auto const y_precision = 0;
146 auto const flags = 0;
147 auto const buttons = 0;
148 auto const modifiers = 0;
149 auto const edge_flags = 0;
150 publisher.publishMotionEvent(++seq, mouse_device, AINPUT_SOURCE_MOUSE,
151 mia::android_pointer_action_from_mir(event.action, event.buttons), flags,
152 edge_flags, modifiers, buttons, x_offset, y_offset, x_precision, y_precision,
153 default_cookie, event.tp, event.tp, 1, &pointer_properties, &pointer_coord);
154 }
155
156 void handle_event(droidinput::InputEvent* event)
157 {
158 if (event->getType() == AINPUT_EVENT_TYPE_KEY)
159 {
160 }
161 else
162 {
163
164 if (mia::android_source_id_is_pointer_device(event->getSource()))
165 {
166 auto mev = static_cast<const droidinput::MotionEvent*>(event);
167 pointer_movement(
168 {mev->getX(0), mev->getY(0)},
169 {mev->getRawAxisValue(AMOTION_EVENT_AXIS_RX, 0),
170 mev->getRawAxisValue(AMOTION_EVENT_AXIS_RY, 0)},
171 {mev->getRawAxisValue(AMOTION_EVENT_AXIS_HSCROLL, 0),
172 mev->getRawAxisValue(AMOTION_EVENT_AXIS_VSCROLL, 0)}
173 );
174 }
175 }
176 }
177 void receive_events()
178 {
179 const auto fake_update_rate = 1ms;
180
181 android::InputEvent *received_event = nullptr;
182 uint32_t seq_id;
183 do
184 {
185 auto result = consumer.consume(&events, true, current_frame_time, &seq_id, &received_event);
186
187 if (result == droidinput::OK)
188 handle_event(received_event);
189
190 if (consumer.hasPendingBatch())
191 current_frame_time += fake_update_rate;
192 } while(consumer.hasPendingBatch() || consumer.hasDeferredEvent());
193 }
194
195 void advance_frame_time_to(std::chrono::milliseconds time)
196 {
197 current_frame_time = time;
198 }
199
200};
201
202TEST_F(InputConsumerTest, emits_single_move_event_on_old_pointer_messages)
203{
204 EXPECT_CALL(*this, pointer_movement(geom::Point{4,11}, geom::Displacement{2,1}, no_scroll));
205
206 send_pointer_event({mir_pointer_action_motion, 0, {2.0, 10.0}, {0.0, 0.0}, no_scroll, 0ns});
207 send_pointer_event({mir_pointer_action_motion, 0, {3.0, 11.0}, {1.0, 1.0}, no_scroll, 1ms});
208 send_pointer_event({mir_pointer_action_motion, 0, {4.0, 11.0}, {1.0, 0.0}, no_scroll, 2ms});
209
210 advance_frame_time_to(16ms);
211 receive_events();
212}
213
214TEST_F(InputConsumerTest, emits_move_events_on_recent_messages)
215{
216 EXPECT_CALL(*this, pointer_movement(geom::Point{10, 5}, geom::Displacement{0, 0}, no_scroll));
217 EXPECT_CALL(*this, pointer_movement(geom::Point{15, 8}, geom::Displacement{5, 3}, no_scroll));
218 EXPECT_CALL(*this, pointer_movement(geom::Point{12,10}, geom::Displacement{-3, 2}, no_scroll));
219
220 send_pointer_event({mir_pointer_action_motion, 0, {10.0, 5.0}, {0.0, 0.0}, no_scroll, 0ns});
221 send_pointer_event({mir_pointer_action_motion, 0, {15.0, 8.0}, {5.0, 3.0}, no_scroll, 1ms});
222 send_pointer_event({mir_pointer_action_motion, 0, {12.0, 10.0}, {-3.0,2.0}, no_scroll, 2ms});
223
224 advance_frame_time_to(2ms);
225 receive_events();
226}
227
228TEST_F(InputConsumerTest, emits_scroll_events_on_each_recent_scroll_messages)
229{
230 EXPECT_CALL(*this, pointer_movement(origin, no_move, geom::Displacement{3, 0}));
231 EXPECT_CALL(*this, pointer_movement(origin, no_move, geom::Displacement{0, 5}));
232 EXPECT_CALL(*this, pointer_movement(origin, no_move, geom::Displacement{2, 5}));
233
234 send_pointer_event({mir_pointer_action_motion, 0, origin, no_move, {3.0, 0.0}, 0ns});
235 send_pointer_event({mir_pointer_action_motion, 0, origin, no_move, {0.0, 5.0}, 1ms});
236 send_pointer_event({mir_pointer_action_motion, 0, origin, no_move, {2.0, 5.0}, 2ms});
237
238 advance_frame_time_to(2ms);
239 receive_events();
240}
241
242TEST_F(InputConsumerTest, emits_accumulated_scroll_event_on_old_messages)
243{
244 EXPECT_CALL(*this, pointer_movement(origin, no_move, geom::Displacement{5, 10}));
245
246 send_pointer_event({mir_pointer_action_motion, 0, origin, no_move, {3.0, 0.0}, 0ns});
247 send_pointer_event({mir_pointer_action_motion, 0, origin, no_move, {0.0, 5.0}, 1ms});
248 send_pointer_event({mir_pointer_action_motion, 0, origin, no_move, {2.0, 5.0}, 2ms});
249
250 advance_frame_time_to(16ms);
251 receive_events();
252}

Subscribers

People subscribed via source and target branches