EventHub: Track the global key and switch states for enabled devices
Querying the global state of pressed keys using the EVIOCGKEY ioctl
seems to affect the stream of events produced by evdev. For instance, if
we query the global state just as the key state happens to have changed
but before the corresponding event notification is sent to the device's
fd, it's possible that the updated state of the key is reflected in the
ioctl without a corresponding input_event being written to the fd.
This means our current model of letting any InputMapper query the global
state of keys is incompatible with the system's behavior, because a
query from one mapper could affect the information available to others.
We resolve this querying the global state of keys and switches exactly
once, immediately after opening the device fd, and tracking the global
state using the events from the fd for the rest of the fd lifecycle.
This way, when a mapper requests the current state of a key, there is no
syscall needed that could potentially affect the input stream.
Bug: 290938220
Bug: 261025260
Test: atest inputflinger_tests --rerun-until-failure -- --test-arg
com.android.tradefed.testtype.GTest:native-test-flag:"--gtest_filter=*StylusButtonIntegration*"
Change-Id: I08376f69fccdc60441eb982d6fee1866bd512de6
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 024187f..6e647db 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -411,7 +411,17 @@
* Note the parameter "bit" is an index to the bit, 0 <= bit < BITS.
*/
inline bool test(size_t bit) const {
- return (bit < BITS) ? mData[bit / WIDTH].test(bit % WIDTH) : false;
+ return (bit < BITS) && mData[bit / WIDTH].test(bit % WIDTH);
+ }
+ /* Sets the given bit in the bit array to given value.
+ * Returns true if the given bit is a valid index and thus was set successfully.
+ */
+ inline bool set(size_t bit, bool value) {
+ if (bit >= BITS) {
+ return false;
+ }
+ mData[bit / WIDTH].set(bit % WIDTH, value);
+ return true;
}
/* Returns total number of bytes needed for the array */
inline size_t bytes() { return (BITS + CHAR_BIT - 1) / CHAR_BIT; }
@@ -653,6 +663,10 @@
void setLedForControllerLocked();
status_t mapLed(int32_t led, int32_t* outScanCode) const;
void setLedStateLocked(int32_t led, bool on);
+
+ bool currentFrameDropped;
+ void trackInputEvent(const struct input_event& event);
+ void readDeviceState();
};
/**