Generate ACTION_CANCEL on joystick disconnect.
Bug: 11480300 Change-Id: I46706838eec0711c6bf345301e7b4ccbad83b063
This commit is contained in:
parent
dcfcf5d0ae
commit
38dcdff308
@ -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;
|
||||
|
@ -158,16 +158,10 @@ void KeyEvent::initialize(const KeyEvent& from) {
|
||||
// --- PointerCoords ---
|
||||
|
||||
float PointerCoords::getAxisValue(int32_t axis) const {
|
||||
if (axis < 0 || axis > 63) {
|
||||
if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t axisBit = 1LL << axis;
|
||||
if (!(bits & axisBit)) {
|
||||
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];
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user