Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38dcdff3 authored by Michael Wright's avatar Michael Wright
Browse files

Generate ACTION_CANCEL on joystick disconnect.

Bug: 11480300
Change-Id: I46706838eec0711c6bf345301e7b4ccbad83b063
parent dcfcf5d0
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -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;
+12 −17
Original line number Diff line number Diff line
@@ -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];
    }
+27 −6
Original line number Diff line number Diff line
@@ -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);
            return true;
                }
        if (actionMasked == AMOTION_EVENT_ACTION_MOVE
                && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
                        | AINPUT_SOURCE_CLASS_NAVIGATION))) {
            } 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 DEBUG_OUTBOUND_EVENT_DETAILS
        ALOGD("Dropping inconsistent motion pointer up/down or move event: "
                "deviceId=%d, source=%08x, actionMasked=%d",