Inputflinger : Use BitArray class to replace raw bytes array.
For EventHub device, use std::bitset vector BitArray to store and input device event driver
property as bitmask, to replace the raw bytes array.
Bug: 160010896
Test: atest EventHubTest, atest inputflinger_tests
Change-Id: I6486535feb097f7dfb24a56f666b1d02ea736a58
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index ee62c9a..baff6e3 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -17,6 +17,8 @@
#ifndef _RUNTIME_EVENT_HUB_H
#define _RUNTIME_EVENT_HUB_H
+#include <bitset>
+#include <climits>
#include <vector>
#include <input/Input.h>
@@ -38,11 +40,6 @@
#include "TouchVideoDevice.h"
-/* Convenience constants. */
-
-#define BTN_FIRST 0x100 // first button code
-#define BTN_LAST 0x15f // last button code
-
namespace android {
/*
@@ -256,6 +253,76 @@
virtual status_t disableDevice(int32_t deviceId) = 0;
};
+template <std::size_t BITS>
+class BitArray {
+ /* Array element type and vector of element type. */
+ using Element = std::uint32_t;
+ /* Number of bits in each BitArray element. */
+ static constexpr size_t WIDTH = sizeof(Element) * CHAR_BIT;
+ /* Number of elements to represent a bit array of the specified size of bits. */
+ static constexpr size_t COUNT = (BITS + WIDTH - 1) / WIDTH;
+
+public:
+ /* BUFFER type declaration for BitArray */
+ using Buffer = std::array<Element, COUNT>;
+ /* To tell if a bit is set in array, it selects an element from the array, and test
+ * if the relevant bit set.
+ * 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;
+ }
+ /* Returns total number of bytes needed for the array */
+ inline size_t bytes() { return (BITS + CHAR_BIT - 1) / CHAR_BIT; }
+ /* Returns true if array contains any non-zero bit from the range defined by start and end
+ * bit index [startIndex, endIndex).
+ */
+ bool any(size_t startIndex, size_t endIndex) {
+ if (startIndex >= endIndex || startIndex > BITS || endIndex > BITS + 1) {
+ ALOGE("Invalid start/end index. start = %zu, end = %zu, total bits = %zu", startIndex,
+ endIndex, BITS);
+ return false;
+ }
+ size_t se = startIndex / WIDTH; // Start of element
+ size_t ee = endIndex / WIDTH; // End of element
+ size_t si = startIndex % WIDTH; // Start index in start element
+ size_t ei = endIndex % WIDTH; // End index in end element
+ // Need to check first unaligned bitset for any non zero bit
+ if (si > 0) {
+ size_t nBits = se == ee ? ei - si : WIDTH - si;
+ // Generate the mask of interested bit range
+ Element mask = ((1 << nBits) - 1) << si;
+ if (mData[se++].to_ulong() & mask) {
+ return true;
+ }
+ }
+ // Check whole bitset for any bit set
+ for (; se < ee; se++) {
+ if (mData[se].any()) {
+ return true;
+ }
+ }
+ // Need to check last unaligned bitset for any non zero bit
+ if (ei > 0 && se <= ee) {
+ // Generate the mask of interested bit range
+ Element mask = (1 << ei) - 1;
+ if (mData[se].to_ulong() & mask) {
+ return true;
+ }
+ }
+ return false;
+ }
+ /* Load bit array values from buffer */
+ void loadFromBuffer(const Buffer& buffer) {
+ for (size_t i = 0; i < COUNT; i++) {
+ mData[i] = std::bitset<WIDTH>(buffer[i]);
+ }
+ }
+
+private:
+ std::array<std::bitset<WIDTH>, COUNT> mData;
+};
+
class EventHub : public EventHubInterface {
public:
EventHub();
@@ -332,13 +399,15 @@
uint32_t classes;
- uint8_t keyBitmask[(KEY_MAX + 1) / 8];
- uint8_t absBitmask[(ABS_MAX + 1) / 8];
- uint8_t relBitmask[(REL_MAX + 1) / 8];
- uint8_t swBitmask[(SW_MAX + 1) / 8];
- uint8_t ledBitmask[(LED_MAX + 1) / 8];
- uint8_t ffBitmask[(FF_MAX + 1) / 8];
- uint8_t propBitmask[(INPUT_PROP_MAX + 1) / 8];
+ BitArray<KEY_MAX> keyBitmask;
+ BitArray<KEY_MAX> keyState;
+ BitArray<ABS_MAX> absBitmask;
+ BitArray<REL_MAX> relBitmask;
+ BitArray<SW_MAX> swBitmask;
+ BitArray<SW_MAX> swState;
+ BitArray<LED_MAX> ledBitmask;
+ BitArray<FF_MAX> ffBitmask;
+ BitArray<INPUT_PROP_MAX> propBitmask;
std::string configurationFile;
PropertyMap* configuration;
@@ -371,6 +440,21 @@
}
return keyMap.keyCharacterMap;
}
+
+ template <std::size_t N>
+ status_t readDeviceBitMask(unsigned long ioctlCode, BitArray<N>& bitArray) {
+ if (!hasValidFd()) {
+ return BAD_VALUE;
+ }
+ if ((_IOC_SIZE(ioctlCode) == 0)) {
+ ioctlCode |= _IOC(0, 0, 0, bitArray.bytes());
+ }
+
+ typename BitArray<N>::Buffer buffer;
+ status_t ret = ioctl(fd, ioctlCode, buffer.data());
+ bitArray.loadFromBuffer(buffer);
+ return ret;
+ }
};
status_t openDeviceLocked(const std::string& devicePath);