diff options
author | Michael Wright <michaelwr@google.com> | 2014-03-19 12:06:10 -0700 |
---|---|---|
committer | Michael Wright <michaelwr@google.com> | 2014-03-20 01:54:00 +0000 |
commit | 38dcdff3087f01ba02aabfc17b3ff6c549bb5707 (patch) | |
tree | f861bff2dbe693469c94f08c7bbf085144120050 | |
parent | dcfcf5d0ae73b79af60da5e72c070c481ffb1189 (diff) | |
download | frameworks_native-38dcdff3087f01ba02aabfc17b3ff6c549bb5707.zip frameworks_native-38dcdff3087f01ba02aabfc17b3ff6c549bb5707.tar.gz frameworks_native-38dcdff3087f01ba02aabfc17b3ff6c549bb5707.tar.bz2 |
Generate ACTION_CANCEL on joystick disconnect.
Bug: 11480300
Change-Id: I46706838eec0711c6bf345301e7b4ccbad83b063
-rw-r--r-- | include/input/Input.h | 11 | ||||
-rw-r--r-- | libs/input/Input.cpp | 29 | ||||
-rw-r--r-- | services/inputflinger/InputDispatcher.cpp | 33 |
3 files changed, 47 insertions, 26 deletions
diff --git a/include/input/Input.h b/include/input/Input.h index ea9c4c2..bb5ceaf 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -22,11 +22,12 @@ */ #include <android/input.h> -#include <utils/Vector.h> +#include <utils/BitSet.h> #include <utils/KeyedVector.h> -#include <utils/Timers.h> #include <utils/RefBase.h> #include <utils/String8.h> +#include <utils/Timers.h> +#include <utils/Vector.h> /* * Additional private constants not defined in ndk/ui/input.h. @@ -205,7 +206,11 @@ struct PointerCoords { float values[MAX_AXES]; inline void clear() { - bits = 0; + BitSet64::clear(bits); + } + + bool isEmpty() const { + return BitSet64::isEmpty(bits); } float getAxisValue(int32_t axis) const; diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index ccbf52b..d9f22e9 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -158,16 +158,10 @@ void KeyEvent::initialize(const KeyEvent& from) { // --- PointerCoords --- float PointerCoords::getAxisValue(int32_t axis) const { - if (axis < 0 || axis > 63) { - return 0; - } - - uint64_t axisBit = 1LL << axis; - if (!(bits & axisBit)) { + if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){ return 0; } - uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL)); - return values[index]; + return values[BitSet64::getIndexOfBit(bits, axis)]; } status_t PointerCoords::setAxisValue(int32_t axis, float value) { @@ -175,22 +169,23 @@ status_t PointerCoords::setAxisValue(int32_t axis, float value) { return NAME_NOT_FOUND; } - uint64_t axisBit = 1LL << axis; - uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL)); - if (!(bits & axisBit)) { + uint32_t index = BitSet64::getIndexOfBit(bits, axis); + if (!BitSet64::hasBit(bits, axis)) { if (value == 0) { return OK; // axes with value 0 do not need to be stored } - uint32_t count = __builtin_popcountll(bits); + + uint32_t count = BitSet64::count(bits); if (count >= MAX_AXES) { tooManyAxes(axis); return NO_MEMORY; } - bits |= axisBit; + BitSet64::markBit(bits, axis); for (uint32_t i = count; i > index; i--) { values[i] = values[i - 1]; } } + values[index] = value; return OK; } @@ -222,7 +217,7 @@ void PointerCoords::applyOffset(float xOffset, float yOffset) { status_t PointerCoords::readFromParcel(Parcel* parcel) { bits = parcel->readInt64(); - uint32_t count = __builtin_popcountll(bits); + uint32_t count = BitSet64::count(bits); if (count > MAX_AXES) { return BAD_VALUE; } @@ -236,7 +231,7 @@ status_t PointerCoords::readFromParcel(Parcel* parcel) { status_t PointerCoords::writeToParcel(Parcel* parcel) const { parcel->writeInt64(bits); - uint32_t count = __builtin_popcountll(bits); + uint32_t count = BitSet64::count(bits); for (uint32_t i = 0; i < count; i++) { parcel->writeFloat(values[i]); } @@ -253,7 +248,7 @@ bool PointerCoords::operator==(const PointerCoords& other) const { if (bits != other.bits) { return false; } - uint32_t count = __builtin_popcountll(bits); + uint32_t count = BitSet64::count(bits); for (uint32_t i = 0; i < count; i++) { if (values[i] != other.values[i]) { return false; @@ -264,7 +259,7 @@ bool PointerCoords::operator==(const PointerCoords& other) const { void PointerCoords::copyFrom(const PointerCoords& other) { bits = other.bits; - uint32_t count = __builtin_popcountll(bits); + uint32_t count = BitSet64::count(bits); for (uint32_t i = 0; i < count; i++) { values[i] = other.values[i]; } diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp index f933681..56044ee 100644 --- a/services/inputflinger/InputDispatcher.cpp +++ b/services/inputflinger/InputDispatcher.cpp @@ -4108,18 +4108,39 @@ bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, case AMOTION_EVENT_ACTION_POINTER_UP: case AMOTION_EVENT_ACTION_POINTER_DOWN: case AMOTION_EVENT_ACTION_MOVE: { + if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) { + // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to + // generate cancellation events for these since they're based in relative rather than + // absolute units. + return true; + } + ssize_t index = findMotionMemento(entry, false /*hovering*/); + + if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) { + // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all + // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any + // other value and we need to track the motion so we can send cancellation events for + // anything generating fallback events (e.g. DPad keys for joystick movements). + if (index >= 0) { + if (entry->pointerCoords[0].isEmpty()) { + mMotionMementos.removeAt(index); + } else { + MotionMemento& memento = mMotionMementos.editItemAt(index); + memento.setPointers(entry); + } + } else if (!entry->pointerCoords[0].isEmpty()) { + addMotionMemento(entry, flags, false /*hovering*/); + } + + // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP. + return true; + } if (index >= 0) { MotionMemento& memento = mMotionMementos.editItemAt(index); memento.setPointers(entry); return true; } - if (actionMasked == AMOTION_EVENT_ACTION_MOVE - && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK - | AINPUT_SOURCE_CLASS_NAVIGATION))) { - // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP. - return true; - } #if DEBUG_OUTBOUND_EVENT_DETAILS ALOGD("Dropping inconsistent motion pointer up/down or move event: " "deviceId=%d, source=%08x, actionMasked=%d", |