summaryrefslogtreecommitdiff
path: root/libs/input/Input.cpp
diff options
context:
space:
mode:
author Siarhei Vishniakou <svv@google.com> 2022-05-26 00:36:48 +0000
committer Siarhei Vishniakou <svv@google.com> 2022-06-03 18:04:17 +0000
commit4ded0b06035d9e69ef88c5ccd0a794eb3104ad5c (patch)
treea086c71cc555595eaeefd8a9a186ea52765f9133 /libs/input/Input.cpp
parente9d6733f53676f18a716c82425ed61bf030215a4 (diff)
Validate indices when requesting PointerCoords
We are investigating a crash in PointerCoords. To further understand what kind of MotionEvents we are dealing with, let's add some assertions to the PointerCoords that we are producing. It's possible that pointerCount is zero, for example. This would help us further narrow down the issue. In this CL, we are also adding a way to dump MotionEvent. This was loosely following MotionEvent.java::toString() method. At some point, we should remove the Java method implementation and replace it with a single jni call to native. That work is out of scope for this CL. In the jni layer, we can't remove the error checking/exception raising, because someone might be catching an exception and moving on, and a native crash would break this pattern. We can consider doing that in the future under an experiment flag, though. Bug: 233163975 Test: printed MotionEvent in log to see the formatting Change-Id: I4f641c0cb89526a06146e4c0cf3a5fab2faa42f8
Diffstat (limited to 'libs/input/Input.cpp')
-rw-r--r--libs/input/Input.cpp71
1 files changed, 69 insertions, 2 deletions
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index fe1754c78b..13ca9ecd35 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -22,7 +22,9 @@
#include <inttypes.h>
#include <string.h>
+#include <android-base/logging.h>
#include <android-base/stringprintf.h>
+#include <cutils/compiler.h>
#include <gui/constants.h>
#include <input/DisplayViewport.h>
#include <input/Input.h>
@@ -542,7 +544,14 @@ void MotionEvent::setCursorPosition(float x, float y) {
}
const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
- return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
+ if (CC_UNLIKELY(pointerIndex < 0 || pointerIndex >= getPointerCount())) {
+ LOG(FATAL) << __func__ << ": Invalid pointer index " << pointerIndex << " for " << *this;
+ }
+ const size_t position = getHistorySize() * getPointerCount() + pointerIndex;
+ if (CC_UNLIKELY(position < 0 || position >= mSamplePointerCoords.size())) {
+ LOG(FATAL) << __func__ << ": Invalid array index " << position << " for " << *this;
+ }
+ return &mSamplePointerCoords[position];
}
float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
@@ -555,7 +564,18 @@ float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
size_t pointerIndex, size_t historicalIndex) const {
- return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
+ if (CC_UNLIKELY(pointerIndex < 0 || pointerIndex >= getPointerCount())) {
+ LOG(FATAL) << __func__ << ": Invalid pointer index " << pointerIndex << " for " << *this;
+ }
+ if (CC_UNLIKELY(historicalIndex < 0 || historicalIndex > getHistorySize())) {
+ LOG(FATAL) << __func__ << ": Invalid historical index " << historicalIndex << " for "
+ << *this;
+ }
+ const size_t position = historicalIndex * getPointerCount() + pointerIndex;
+ if (CC_UNLIKELY(position < 0 || position >= mSamplePointerCoords.size())) {
+ LOG(FATAL) << __func__ << ": Invalid array index " << position << " for " << *this;
+ }
+ return &mSamplePointerCoords[position];
}
float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
@@ -903,6 +923,53 @@ PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source,
return out;
}
+std::ostream& operator<<(std::ostream& out, const MotionEvent& event) {
+ out << "MotionEvent { action=" << MotionEvent::actionToString(event.getAction());
+ if (event.getActionButton() != 0) {
+ out << ", actionButton=" << std::to_string(event.getActionButton());
+ }
+ const size_t pointerCount = event.getPointerCount();
+ for (size_t i = 0; i < pointerCount; i++) {
+ out << ", id[" << i << "]=" << event.getPointerId(i);
+ float x = event.getX(i);
+ float y = event.getY(i);
+ if (x != 0 || y != 0) {
+ out << ", x[" << i << "]=" << x;
+ out << ", y[" << i << "]=" << y;
+ }
+ int toolType = event.getToolType(i);
+ if (toolType != AMOTION_EVENT_TOOL_TYPE_FINGER) {
+ out << ", toolType[" << i << "]=" << toolType;
+ }
+ }
+ if (event.getButtonState() != 0) {
+ out << ", buttonState=" << event.getButtonState();
+ }
+ if (event.getClassification() != MotionClassification::NONE) {
+ out << ", classification=" << motionClassificationToString(event.getClassification());
+ }
+ if (event.getMetaState() != 0) {
+ out << ", metaState=" << event.getMetaState();
+ }
+ if (event.getEdgeFlags() != 0) {
+ out << ", edgeFlags=" << event.getEdgeFlags();
+ }
+ if (pointerCount != 1) {
+ out << ", pointerCount=" << pointerCount;
+ }
+ if (event.getHistorySize() != 0) {
+ out << ", historySize=" << event.getHistorySize();
+ }
+ out << ", eventTime=" << event.getEventTime();
+ out << ", downTime=" << event.getDownTime();
+ out << ", deviceId=" << event.getDeviceId();
+ out << ", source=" << inputEventSourceToString(event.getSource());
+ out << ", displayId=" << event.getDisplayId();
+ out << ", eventId=" << event.getId();
+ out << "}";
+ return out;
+}
+
// --- FocusEvent ---
void FocusEvent::initialize(int32_t id, bool hasFocus) {