Add static_asserts for the size of InputMessage
Inside InputTransport.cpp, we are reading and writing InputMessages.
This is done in the following way:
read
::recv(getFd(), msg, sizeof(InputMessage), MSG_DONTWAIT);
write
::send(getFd(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
We are sending a variable-length message across the socket, and
receiving a maximum of sizeof(InputMessage) when reading it.
In this CL, we are adding asserts on the _maximum_ length of the message
that we would send across the socket. Since we typically only have a few
pointers at most, while MAX_POINTERS=16, in reality the communication
between system_server and app will use much less data.
However, it's still useful to add these asserts to understand the
worst-case scenario of message transfer.
Bug: 167946763
Test: m StructLayout_test
Change-Id: I281ecea62b392dea56936d031ab9c4ee18add93f
diff --git a/include/input/Input.h b/include/input/Input.h
index f4147a0..55ebb90 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -164,7 +164,7 @@
* (We want at least 10 but some touch controllers obstensibly configured for 10 pointers
* will occasionally emit 11. There is not much harm making this constant bigger.)
*/
-#define MAX_POINTERS 16
+static constexpr size_t MAX_POINTERS = 16;
/*
* Maximum number of samples supported per motion event.
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index edcb615..5f9a37d 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -500,24 +500,6 @@
status_t sendTimeline(int32_t inputEventId,
std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);
- /* Returns true if there is a deferred event waiting.
- *
- * Should be called after calling consume() to determine whether the consumer
- * has a deferred event to be processed. Deferred events are somewhat special in
- * that they have already been removed from the input channel. If the input channel
- * becomes empty, the client may need to do extra work to ensure that it processes
- * the deferred event despite the fact that the input channel's file descriptor
- * is not readable.
- *
- * One option is simply to call consume() in a loop until it returns WOULD_BLOCK.
- * This guarantees that all deferred events will be processed.
- *
- * Alternately, the caller can call hasDeferredEvent() to determine whether there is
- * a deferred event waiting and then ensure that its event loop wakes up at least
- * one more time to consume the deferred event.
- */
- bool hasDeferredEvent() const;
-
/* Returns true if there is a pending batch.
*
* Should be called after calling consume() with consumeBatches == false to determine
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index a065ce2..6195052 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -1318,10 +1318,6 @@
return result;
}
-bool InputConsumer::hasDeferredEvent() const {
- return mMsgDeferred;
-}
-
bool InputConsumer::hasPendingBatch() const {
return !mBatches.empty();
}
diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp
index b6a9476..1c8658b 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -115,12 +115,9 @@
static_assert(sizeof(InputMessage::Header) == 8);
}
-/**
- * We cannot use the Body::size() method here because it is not static for
- * the Motion type, where "pointerCount" variable affects the size and can change at runtime.
- */
void TestBodySize() {
static_assert(sizeof(InputMessage::Body::Key) == 96);
+ static_assert(sizeof(InputMessage::Body::Motion::Pointer) == 136);
static_assert(sizeof(InputMessage::Body::Motion) ==
offsetof(InputMessage::Body::Motion, pointers) +
sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS);
@@ -132,6 +129,38 @@
// Timeline
static_assert(GraphicsTimeline::SIZE == 2);
static_assert(sizeof(InputMessage::Body::Timeline) == 24);
+
+ /**
+ * We cannot use the Body::size() method here because it is not static for
+ * the Motion type, where "pointerCount" variable affects the size and can change at runtime.
+ */
+ static_assert(sizeof(InputMessage::Body) ==
+ offsetof(InputMessage::Body::Motion, pointers) +
+ sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS);
+ static_assert(sizeof(InputMessage::Body) == 160 + 136 * 16);
+ static_assert(sizeof(InputMessage::Body) == 2336);
+}
+
+/**
+ * In general, we are sending a variable-length message across the socket, because the number of
+ * pointers varies. When we receive the message, we still need to allocate enough memory for the
+ * entire InputMessage struct. This size is, therefore, the worst case scenario. However, it is
+ * still helpful to compute to get an idea of the sizes that are involved.
+ */
+void TestWorstCaseInputMessageSize() {
+ static_assert(sizeof(InputMessage) == /*header*/ 8 + /*body*/ 2336);
+ static_assert(sizeof(InputMessage) == 2344);
+}
+
+/**
+ * Assuming a single pointer, how big is the message that we are sending across the socket?
+ */
+void CalculateSinglePointerInputMessageSize() {
+ constexpr size_t pointerCount = 1;
+ constexpr size_t bodySize = offsetof(InputMessage::Body::Motion, pointers) +
+ sizeof(InputMessage::Body::Motion::Pointer) * pointerCount;
+ static_assert(bodySize == 160 + 136);
+ static_assert(bodySize == 296); // For the total message size, add the small header
}
// --- VerifiedInputEvent ---
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 3f3c0db..297074a 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -215,7 +215,7 @@
return false;
}
if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
- ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
+ ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %zu.",
pointerCount, MAX_POINTERS);
return false;
}
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index 4bd1cd8..ff3a592 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -282,7 +282,7 @@
if (outCount >= MAX_POINTERS) {
if (DEBUG_POINTERS) {
- ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
+ ALOGD("MultiTouch device %s emitted more than maximum of %zu pointers; "
"ignoring the rest.",
getDeviceName().c_str(), MAX_POINTERS);
}
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 0814bc2..aa2f832 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -558,7 +558,7 @@
MotionEvent event;
PointerProperties pointerProperties[MAX_POINTERS + 1];
PointerCoords pointerCoords[MAX_POINTERS + 1];
- for (int i = 0; i <= MAX_POINTERS; i++) {
+ for (size_t i = 0; i <= MAX_POINTERS; i++) {
pointerProperties[i].clear();
pointerProperties[i].id = i;
pointerCoords[i].clear();