Mir

Merge lp:~mir-team/mir/fix-missing-hover-exit-event into lp:mir

Proposed by Robert Carr
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 2329
Proposed branch: lp:~mir-team/mir/fix-missing-hover-exit-event
Merge into: lp:mir
Diff against target: 113 lines (+39/-33)
2 files modified
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp (+36/-31)
tests/acceptance-tests/throwback/test_client_input.cpp (+3/-2)
To merge this branch: bzr merge lp:~mir-team/mir/fix-missing-hover-exit-event
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Kevin DuBois (community) Approve
Alan Griffiths Approve
Chris Halse Rogers Approve
Daniel van Vugt Abstain
Review via email: mp+249431@code.launchpad.net

Commit message

Enable pointer exit events. (LP: #1418569)

Description of the change

This branch fixes https://bugs.launchpad.net/bugs/1418569 . See the changes to test_client_input for the semantic changes to client.

Doing so required two semantic changes to the input dispatcher stack:

There is a sort of extra layer of paranoia check in the InputDispatcher which prevents events from being dispatched to non foreground windows (e.g. the focused window or the target of the current touch gesture). We need to allow dispatching pointer exit events to the non foreground window though (as this is how they become non foreground!) InputDispatcher.cpp:l1347.

Then around 1226 we assume just because we do not have a touched window there is nothing to dispatch in the touch state so we need to set injection state failed. In fact we need to continue (if the new branch at l1232 is not taken we will fall to 1317) and check if there are hover exit events to dispatch. If there are still no targets (e.g. no touched window (foreground) and no hover exit event) then we can finally abort the dispatch cycle now at l1361

To post a comment you must log in.
Revision history for this message
Robert Carr (robertcarr) wrote :

I accidentally left the debug defines on but I am going to make a case they should be left on.

1. I've turned them on and off dozens of times.
2. They only show up with MIR_SERVER_LEGACY_INPUT_REPORT=log ANDROID_LOG_TAGS=*:v

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

The debug flags need some careful assessment, possibly profiling. All too often formatting hidden debug strings at high frequency can have a significant CPU hit.

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

Rather than forcing someone to go to the trouble of profiling and proving that the debug logging doesn't hurt performance during input, I suggest it's quicker and safer to just not enable the debug flags on trunk.

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

Looks sensible apart from the debug; either verify that it doesn't add significant CPU useage in the non-reporting case, or turn it back off.

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

We should replace the logging with something we can be sure doesn't waste time formatting or on memory allocation. Until then we should have it switched off.

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

Hi guys. I'll change it back of course.

I hate to be snotty but im a little frustrated that this is even brought up. I think everyones intuition that this is something worth being concerned about is incorrect by 6 (!) orders of magnitude. My computer from early 2011 can format 10 million strings in 2.5 seconds as opposed to the 120 input events we see a second.

>> #include <stdio.h>
>> #include <stdlib.h>

>> int main()
>> {
>> for (int i = 0; i < 10000000; i++)
>> {
>> char output[1024];
>> snprintf(output, 1024, "%d %s %d", rand(), "Kittens", i);
>> }
>> }

Revision history for this message
Robert Carr (robertcarr) wrote :

Want to apologize a little for my choice of words. Not actually personally frustrated with anyone :) Obviously we are all concerned about defending the value of Mir.

Just not sure how else to communicate that I think we may be prone to a bit of Fear-Uncertainty-Doubt when it comes to performance.

:)

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 :

Unfortunately this is something learned from experience. Both in previous projects and in Mir last year (see bug 1343074).

Revision history for this message
Daniel van Vugt (vanvugt) :
review: Abstain
Revision history for this message
Robert Carr (robertcarr) wrote :

Fixed stray character at beginning of file.

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

Looks good.

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

OK

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

okay by me

review: Approve
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 '3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp'
2--- 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2015-02-13 06:12:34 +0000
3+++ 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2015-02-18 18:13:06 +0000
4@@ -1224,36 +1224,36 @@
5 "eventually add a new window when it finishes starting up.");
6 goto Unresponsive;
7 }
8-
9- ALOGI("Dropping event because there is no touched window.");
10- injectionResult = INPUT_EVENT_INJECTION_FAILED;
11- goto Failed;
12- }
13- }
14-
15- // Set target flags.
16- int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
17- if (isSplit) {
18- targetFlags |= InputTarget::FLAG_SPLIT;
19- }
20- if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
21- targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
22- }
23-
24- // Update hover state.
25- if (isHoverAction) {
26- newHoverWindowHandle = newTouchedWindowHandle;
27- } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
28- newHoverWindowHandle = mLastHoverWindowHandle;
29- }
30-
31- // Update the temporary touch state.
32- IntSet pointerIds;
33- if (isSplit) {
34- int32_t pointerId = entry->pointerProperties[pointerIndex].id;
35- pointerIds.insert(pointerId);
36- }
37- mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
38+ }
39+ }
40+
41+ // We may still not have a window handle but we can't just abort the dispatch
42+ // cycle because there could be hover exits to dispatch.
43+ if (newTouchedWindowHandle != NULL) {
44+ // Set target flags.
45+ int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
46+ if (isSplit) {
47+ targetFlags |= InputTarget::FLAG_SPLIT;
48+ }
49+ if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
50+ targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
51+ }
52+
53+ // Update hover state.
54+ if (isHoverAction) {
55+ newHoverWindowHandle = newTouchedWindowHandle;
56+ } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
57+ newHoverWindowHandle = mLastHoverWindowHandle;
58+ }
59+
60+ // Update the temporary touch state.
61+ IntSet pointerIds;
62+ if (isSplit) {
63+ int32_t pointerId = entry->pointerProperties[pointerIndex].id;
64+ pointerIds.insert(pointerId);
65+ }
66+ mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
67+ }
68 } else {
69 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
70
71@@ -1277,6 +1277,9 @@
72 sp<InputWindowHandle> oldTouchedWindowHandle =
73 mTempTouchState.getFirstForegroundWindowHandle();
74 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(x, y);
75+
76+ newHoverWindowHandle = newTouchedWindowHandle;
77+
78 if (oldTouchedWindowHandle != newTouchedWindowHandle
79 && newTouchedWindowHandle != NULL) {
80 #if DEBUG_FOCUS
81@@ -1339,7 +1342,9 @@
82 bool haveForegroundWindow = false;
83 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
84 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
85- if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
86+ if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND ||
87+ // We allow dispatching hover exit events to non foreground windows.
88+ touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
89 haveForegroundWindow = true;
90 if (! checkInjectionPermission(touchedWindow.windowHandle,
91 entry->injectionState)) {
92
93=== modified file 'tests/acceptance-tests/throwback/test_client_input.cpp'
94--- tests/acceptance-tests/throwback/test_client_input.cpp 2015-02-13 06:12:34 +0000
95+++ tests/acceptance-tests/throwback/test_client_input.cpp 2015-02-18 18:13:06 +0000
96@@ -271,7 +271,7 @@
97 mis::a_key_down_event().of_scancode(KEY_4));
98 }
99
100-TEST_F(TestClientInput, clients_receive_pointer_inside_window)
101+TEST_F(TestClientInput, clients_receive_pointer_inside_window_and_crossing_events)
102 {
103 using namespace testing;
104
105@@ -285,7 +285,8 @@
106 handle_input(
107 mt::PointerEventWithPosition(
108 InputClient::surface_width - 1,
109- InputClient::surface_height - 1)))
110+ InputClient::surface_height - 1)));
111+ EXPECT_CALL(client.handler, handle_input(mt::PointerLeaveEvent()))
112 .WillOnce(mt::WakeUp(&client.all_events_received));
113 // But we should not receive an event for the second movement outside of our surface!
114

Subscribers

People subscribed via source and target branches