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

Commit f16c26de authored by Jeff Brown's avatar Jeff Brown
Browse files

More native input dispatch work.

Removed old input dispatch code.
Refactored the policy callbacks.
Pushed a tiny bit of the power manager state down to native.
Fixed long press on MENU.
Made the virtual key detection and cancelation a bit more precise.

Change-Id: I5d8c1062f7ea0ab3b54c6fadb058c4d5f5a9e02e
parent bf83375c
Loading
Loading
Loading
Loading
+10 −5
Original line number Original line Diff line number Diff line
@@ -250,7 +250,13 @@ struct InputDevice {
        nsecs_t downTime;
        nsecs_t downTime;


        struct CurrentVirtualKeyState {
        struct CurrentVirtualKeyState {
            bool down;
            enum Status {
                STATUS_UP,
                STATUS_DOWN,
                STATUS_CANCELED
            };

            Status status;
            nsecs_t downTime;
            nsecs_t downTime;
            int32_t keyCode;
            int32_t keyCode;
            int32_t scanCode;
            int32_t scanCode;
@@ -295,6 +301,7 @@ struct InputDevice {
        void calculatePointerIds();
        void calculatePointerIds();


        bool isPointInsideDisplay(int32_t x, int32_t y) const;
        bool isPointInsideDisplay(int32_t x, int32_t y) const;
        const InputDevice::VirtualKey* findVirtualKeyHit() const;
    };
    };


    InputDevice(int32_t id, uint32_t classes, String8 name);
    InputDevice(int32_t id, uint32_t classes, String8 name);
@@ -390,11 +397,9 @@ public:
    virtual bool getDisplayInfo(int32_t displayId,
    virtual bool getDisplayInfo(int32_t displayId,
            int32_t* width, int32_t* height, int32_t* orientation) = 0;
            int32_t* width, int32_t* height, int32_t* orientation) = 0;


    /* Provides feedback for a virtual key.
    /* Provides feedback for a virtual key down.
     */
     */
    virtual void virtualKeyFeedback(nsecs_t when, int32_t deviceId,
    virtual void virtualKeyDownFeedback() = 0;
            int32_t action, int32_t flags, int32_t keyCode,
            int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;


    /* Intercepts a key event.
    /* Intercepts a key event.
     * The policy can use this method as an opportunity to perform power management functions
     * The policy can use this method as an opportunity to perform power management functions
+5 −2
Original line number Original line Diff line number Diff line
@@ -299,14 +299,13 @@ void InputDispatcher::processKeyRepeatLockedInterruptible(
    uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
    uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
    if (entry->refCount == 1) {
    if (entry->refCount == 1) {
        entry->eventTime = currentTime;
        entry->eventTime = currentTime;
        entry->downTime = currentTime;
        entry->policyFlags = policyFlags;
        entry->policyFlags = policyFlags;
        entry->repeatCount += 1;
        entry->repeatCount += 1;
    } else {
    } else {
        KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
        KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
                entry->deviceId, entry->nature, policyFlags,
                entry->deviceId, entry->nature, policyFlags,
                entry->action, entry->flags, entry->keyCode, entry->scanCode,
                entry->action, entry->flags, entry->keyCode, entry->scanCode,
                entry->metaState, entry->repeatCount + 1, currentTime);
                entry->metaState, entry->repeatCount + 1, entry->downTime);


        mKeyRepeatState.lastKeyEntry = newEntry;
        mKeyRepeatState.lastKeyEntry = newEntry;
        mAllocator.releaseKeyEntry(entry);
        mAllocator.releaseKeyEntry(entry);
@@ -314,6 +313,10 @@ void InputDispatcher::processKeyRepeatLockedInterruptible(
        entry = newEntry;
        entry = newEntry;
    }
    }


    if (entry->repeatCount == 1) {
        entry->flags |= KEY_EVENT_FLAG_LONG_PRESS;
    }

    mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout;
    mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout;


#if DEBUG_OUTBOUND_EVENT_DETAILS
#if DEBUG_OUTBOUND_EVENT_DETAILS
+74 −54
Original line number Original line Diff line number Diff line
@@ -189,7 +189,7 @@ void InputDevice::TrackballState::reset() {
void InputDevice::TouchScreenState::reset() {
void InputDevice::TouchScreenState::reset() {
    lastTouch.clear();
    lastTouch.clear();
    downTime = 0;
    downTime = 0;
    currentVirtualKey.down = false;
    currentVirtualKey.status = CurrentVirtualKeyState::STATUS_UP;


    for (uint32_t i = 0; i < MAX_POINTERS; i++) {
    for (uint32_t i = 0; i < MAX_POINTERS; i++) {
        averagingTouchFilter.historyStart[i] = 0;
        averagingTouchFilter.historyStart[i] = 0;
@@ -746,6 +746,29 @@ bool InputDevice::TouchScreenState::isPointInsideDisplay(int32_t x, int32_t y) c
        && y <= parameters.yAxis.maxValue;
        && y <= parameters.yAxis.maxValue;
}
}


const InputDevice::VirtualKey* InputDevice::TouchScreenState::findVirtualKeyHit() const {
    int32_t x = currentTouch.pointers[0].x;
    int32_t y = currentTouch.pointers[0].y;
    for (size_t i = 0; i < virtualKeys.size(); i++) {
        const InputDevice::VirtualKey& virtualKey = virtualKeys[i];

#if DEBUG_VIRTUAL_KEYS
        LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
                "left=%d, top=%d, right=%d, bottom=%d",
                x, y,
                virtualKey.keyCode, virtualKey.scanCode,
                virtualKey.hitLeft, virtualKey.hitTop,
                virtualKey.hitRight, virtualKey.hitBottom);
#endif

        if (virtualKey.isHit(x, y)) {
            return & virtualKey;
        }
    }

    return NULL;
}



// --- InputDevice::SingleTouchScreenState ---
// --- InputDevice::SingleTouchScreenState ---


@@ -1269,82 +1292,77 @@ void InputReader::onTouchScreenChanged(nsecs_t when,


bool InputReader::consumeVirtualKeyTouches(nsecs_t when,
bool InputReader::consumeVirtualKeyTouches(nsecs_t when,
        InputDevice* device, uint32_t policyFlags) {
        InputDevice* device, uint32_t policyFlags) {
    if (device->touchScreen.currentVirtualKey.down) {
    switch (device->touchScreen.currentVirtualKey.status) {
    case InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_CANCELED:
        if (device->touchScreen.currentTouch.pointerCount == 0) {
        if (device->touchScreen.currentTouch.pointerCount == 0) {
            // Pointer went up while virtual key was down.  Send key up event.
            // Pointer went up after virtual key canceled.
            device->touchScreen.currentVirtualKey.down = false;
            device->touchScreen.currentVirtualKey.status =
                    InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_UP;
        }
        return true; // consumed


    case InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN:
        if (device->touchScreen.currentTouch.pointerCount == 0) {
            // Pointer went up while virtual key was down.
            device->touchScreen.currentVirtualKey.status =
                    InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_UP;
#if DEBUG_VIRTUAL_KEYS
#if DEBUG_VIRTUAL_KEYS
            LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
            LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
                    device->touchScreen.currentVirtualKey.keyCode,
                    device->touchScreen.currentVirtualKey.keyCode,
                    device->touchScreen.currentVirtualKey.scanCode);
                    device->touchScreen.currentVirtualKey.scanCode);
#endif
#endif

            dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
            dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
                    KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
                    KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
            return true; // consumed
            return true; // consumed
        }
        }


        int32_t x = device->touchScreen.currentTouch.pointers[0].x;
        if (device->touchScreen.currentTouch.pointerCount == 1) {
        int32_t y = device->touchScreen.currentTouch.pointers[0].y;
            const InputDevice::VirtualKey* virtualKey = device->touchScreen.findVirtualKeyHit();
        if (device->touchScreen.isPointInsideDisplay(x, y)
            if (virtualKey
                || device->touchScreen.currentTouch.pointerCount != 1) {
                    && virtualKey->keyCode == device->touchScreen.currentVirtualKey.keyCode) {
            // Pointer moved inside the display area or another pointer also went down.
                // Pointer is still within the space of the virtual key.
            // Send key cancellation.
                return true; // consumed
            device->touchScreen.currentVirtualKey.down = false;
            }
        }


        // Pointer left virtual key area or another pointer also went down.
        // Send key cancellation.
        device->touchScreen.currentVirtualKey.status =
                InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_CANCELED;
#if DEBUG_VIRTUAL_KEYS
#if DEBUG_VIRTUAL_KEYS
        LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
        LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
                device->touchScreen.currentVirtualKey.keyCode,
                device->touchScreen.currentVirtualKey.keyCode,
                device->touchScreen.currentVirtualKey.scanCode);
                device->touchScreen.currentVirtualKey.scanCode);
#endif
#endif

        dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
        dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
                KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY
                KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY
                        | KEY_EVENT_FLAG_CANCELED);
                        | KEY_EVENT_FLAG_CANCELED);
        return true; // consumed


            // Clear the last touch data so we will consider the pointer as having just been
    default:
            // pressed down when generating subsequent motion events.
        if (device->touchScreen.currentTouch.pointerCount == 1
            device->touchScreen.lastTouch.clear();
            return false; // not consumed
        }
    } else if (device->touchScreen.currentTouch.pointerCount == 1
                && device->touchScreen.lastTouch.pointerCount == 0) {
                && device->touchScreen.lastTouch.pointerCount == 0) {
        int32_t x = device->touchScreen.currentTouch.pointers[0].x;
            // Pointer just went down.  Check for virtual key hit.
        int32_t y = device->touchScreen.currentTouch.pointers[0].y;
            const InputDevice::VirtualKey* virtualKey = device->touchScreen.findVirtualKeyHit();
        for (size_t i = 0; i < device->touchScreen.virtualKeys.size(); i++) {
            if (virtualKey) {
            const InputDevice::VirtualKey& virtualKey = device->touchScreen.virtualKeys[i];
                device->touchScreen.currentVirtualKey.status =

                        InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN;
#if DEBUG_VIRTUAL_KEYS
            LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
                    "left=%d, top=%d, right=%d, bottom=%d",
                    x, y,
                    virtualKey.keyCode, virtualKey.scanCode,
                    virtualKey.hitLeft, virtualKey.hitTop,
                    virtualKey.hitRight, virtualKey.hitBottom);
#endif

            if (virtualKey.isHit(x, y)) {
                device->touchScreen.currentVirtualKey.down = true;
                device->touchScreen.currentVirtualKey.downTime = when;
                device->touchScreen.currentVirtualKey.downTime = when;
                device->touchScreen.currentVirtualKey.keyCode = virtualKey.keyCode;
                device->touchScreen.currentVirtualKey.keyCode = virtualKey->keyCode;
                device->touchScreen.currentVirtualKey.scanCode = virtualKey.scanCode;
                device->touchScreen.currentVirtualKey.scanCode = virtualKey->scanCode;

#if DEBUG_VIRTUAL_KEYS
#if DEBUG_VIRTUAL_KEYS
                LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
                LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
                        device->touchScreen.currentVirtualKey.keyCode,
                        device->touchScreen.currentVirtualKey.keyCode,
                        device->touchScreen.currentVirtualKey.scanCode);
                        device->touchScreen.currentVirtualKey.scanCode);
#endif
#endif

                dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_DOWN,
                dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_DOWN,
                        KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
                        KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
                return true; // consumed
                return true; // consumed
            }
            }
        }
        }
    }

        return false; // not consumed
        return false; // not consumed
    }
    }
}


void InputReader::dispatchVirtualKey(nsecs_t when,
void InputReader::dispatchVirtualKey(nsecs_t when,
        InputDevice* device, uint32_t policyFlags,
        InputDevice* device, uint32_t policyFlags,
@@ -1356,8 +1374,9 @@ void InputReader::dispatchVirtualKey(nsecs_t when,
    nsecs_t downTime = device->touchScreen.currentVirtualKey.downTime;
    nsecs_t downTime = device->touchScreen.currentVirtualKey.downTime;
    int32_t metaState = globalMetaState();
    int32_t metaState = globalMetaState();


    mPolicy->virtualKeyFeedback(when, device->id, keyEventAction, keyEventFlags,
    if (keyEventAction == KEY_EVENT_ACTION_DOWN) {
            keyCode, scanCode, metaState, downTime);
        mPolicy->virtualKeyDownFeedback();
    }


    int32_t policyActions = mPolicy->interceptKey(when, device->id,
    int32_t policyActions = mPolicy->interceptKey(when, device->id,
            keyEventAction == KEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
            keyEventAction == KEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
@@ -1852,7 +1871,7 @@ void InputReader::configureVirtualKeys(InputDevice* device) {
        uint32_t flags;
        uint32_t flags;
        if (mEventHub->scancodeToKeycode(device->id, virtualKey.scanCode,
        if (mEventHub->scancodeToKeycode(device->id, virtualKey.scanCode,
                & keyCode, & flags)) {
                & keyCode, & flags)) {
            LOGI("  VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
            LOGW("  VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
            device->touchScreen.virtualKeys.pop(); // drop the key
            device->touchScreen.virtualKeys.pop(); // drop the key
            continue;
            continue;
        }
        }
@@ -1933,7 +1952,8 @@ void InputReader::updateExportedVirtualKeyState() {
    for (size_t i = 0; i < mDevices.size(); i++) {
    for (size_t i = 0; i < mDevices.size(); i++) {
        InputDevice* device = mDevices.valueAt(i);
        InputDevice* device = mDevices.valueAt(i);
        if (device->isTouchScreen()) {
        if (device->isTouchScreen()) {
            if (device->touchScreen.currentVirtualKey.down) {
            if (device->touchScreen.currentVirtualKey.status
                    == InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN) {
                keyCode = device->touchScreen.currentVirtualKey.keyCode;
                keyCode = device->touchScreen.currentVirtualKey.keyCode;
                scanCode = device->touchScreen.currentVirtualKey.scanCode;
                scanCode = device->touchScreen.currentVirtualKey.scanCode;
            }
            }