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

Commit 54977db2 authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

am 55198db2: am 4dac901f: Rewrite touch navigation dpad synthesis.

* commit '55198db2':
  Rewrite touch navigation dpad synthesis.
parents 1467991f 55198db2
Loading
Loading
Loading
Loading
+371 −245

File changed.

Preview size limit exceeded, changes collapsed.

+31 −5
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@
#include <androidfw/KeyCharacterMap.h>
#include <androidfw/VirtualKeyMap.h>

#include <sha1.h>
#include <string.h>
#include <stdint.h>
#include <dirent.h>
@@ -49,6 +48,7 @@
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/limits.h>
#include <sys/sha1.h>

/* this macro is used to tell if "bit" is set in "array"
 * it selects a byte from the array, and does a boolean AND
@@ -162,7 +162,8 @@ EventHub::Device::Device(int fd, int32_t id, const String8& path,
        next(NULL),
        fd(fd), id(id), path(path), identifier(identifier),
        classes(0), configuration(NULL), virtualKeyMap(NULL),
        ffEffectPlaying(false), ffEffectId(-1) {
        ffEffectPlaying(false), ffEffectId(-1),
        timestampOverrideSec(0), timestampOverrideUsec(0) {
    memset(keyBitmask, 0, sizeof(keyBitmask));
    memset(absBitmask, 0, sizeof(absBitmask));
    memset(relBitmask, 0, sizeof(relBitmask));
@@ -766,12 +767,37 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz

                    size_t count = size_t(readSize) / sizeof(struct input_event);
                    for (size_t i = 0; i < count; i++) {
                        const struct input_event& iev = readBuffer[i];
                        ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d",
                        struct input_event& iev = readBuffer[i];
                        ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d",
                                device->path.string(),
                                (int) iev.time.tv_sec, (int) iev.time.tv_usec,
                                iev.type, iev.code, iev.value);

                        // Some input devices may have a better concept of the time
                        // when an input event was actually generated than the kernel
                        // which simply timestamps all events on entry to evdev.
                        // This is a custom Android extension of the input protocol
                        // mainly intended for use with uinput based device drivers.
                        if (iev.type == EV_MSC) {
                            if (iev.code == MSC_ANDROID_TIME_SEC) {
                                device->timestampOverrideSec = iev.value;
                                continue;
                            } else if (iev.code == MSC_ANDROID_TIME_USEC) {
                                device->timestampOverrideUsec = iev.value;
                                continue;
                            }
                        }
                        if (device->timestampOverrideSec || device->timestampOverrideUsec) {
                            iev.time.tv_sec = device->timestampOverrideSec;
                            iev.time.tv_usec = device->timestampOverrideUsec;
                            if (iev.type == EV_SYN && iev.code == SYN_REPORT) {
                                device->timestampOverrideSec = 0;
                                device->timestampOverrideUsec = 0;
                            }
                            ALOGV("applied override time %d.%06d",
                                    int(iev.time.tv_sec), int(iev.time.tv_usec));
                        }

#ifdef HAVE_POSIX_CLOCKS
                        // Use the time specified in the event instead of the current time
                        // so that downstream code can get more accurate estimates of
@@ -829,8 +855,8 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
                        event->code = iev.code;
                        event->value = iev.value;
                        event += 1;
                        capacity -= 1;
                    }
                    capacity -= count;
                    if (capacity == 0) {
                        // The result buffer is full.  Reset the pending event index
                        // so we will try to read the device again on the next iteration.
+17 −0
Original line number Diff line number Diff line
@@ -42,6 +42,20 @@
#define BTN_FIRST 0x100  // first button code
#define BTN_LAST 0x15f   // last button code

/*
 * These constants are used privately in Android to pass raw timestamps
 * through evdev from uinput device drivers because there is currently no
 * other way to transfer this information.  The evdev driver automatically
 * timestamps all input events with the time they were posted and clobbers
 * whatever information was passed in.
 *
 * For the purposes of this hack, the timestamp is specified in the
 * CLOCK_MONOTONIC timebase and is split into two EV_MSC events specifying
 * seconds and microseconds.
 */
#define MSC_ANDROID_TIME_SEC 0x6
#define MSC_ANDROID_TIME_USEC 0x7

namespace android {

enum {
@@ -329,6 +343,9 @@ private:
        bool ffEffectPlaying;
        int16_t ffEffectId; // initially -1

        int32_t timestampOverrideSec;
        int32_t timestampOverrideUsec;

        Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier);
        ~Device();

+56 −5
Original line number Diff line number Diff line
@@ -2701,6 +2701,12 @@ void TouchInputMapper::dump(String8& dump) {
                mPointerYZoomScale);
        dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
                mPointerGestureMaxSwipeWidth);
    } else if (mDeviceMode == DEVICE_MODE_NAVIGATION) {
        dump.appendFormat(INDENT3 "Navigation Gesture Detector:\n");
        dump.appendFormat(INDENT4 "AssistStartY: %0.3f\n",
                mNavigationAssistStartY);
        dump.appendFormat(INDENT4 "AssistEndY: %0.3f\n",
                mNavigationAssistEndY);
    }
}

@@ -2895,7 +2901,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
        }
    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
        mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
        mDeviceMode = DEVICE_MODE_UNSCALED;
        mDeviceMode = DEVICE_MODE_NAVIGATION;
    } else {
        mSource = AINPUT_SOURCE_TOUCHPAD;
        mDeviceMode = DEVICE_MODE_UNSCALED;
@@ -3243,8 +3249,8 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
            break;
        }

        // Compute pointer gesture detection parameters.
        if (mDeviceMode == DEVICE_MODE_POINTER) {
            // Compute pointer gesture detection parameters.
            float rawDiagonal = hypotf(rawWidth, rawHeight);
            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);

@@ -3269,10 +3275,14 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
            // translated into freeform gestures.
            mPointerGestureMaxSwipeWidth =
                    mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
        }

            // Abort current pointer usages because the state has changed.
            abortPointerUsage(when, 0 /*policyFlags*/);
        } else if (mDeviceMode == DEVICE_MODE_NAVIGATION) {
            // Compute navigation parameters.
            mNavigationAssistStartY = mSurfaceHeight * 0.9f;
            mNavigationAssistEndY = mSurfaceHeight * 0.5f;
        }

        // Inform the dispatcher about the changes.
        *outResetNeeded = true;
@@ -3611,6 +3621,7 @@ void TouchInputMapper::reset(nsecs_t when) {

    mPointerGesture.reset();
    mPointerSimple.reset();
    mNavigation.reset();

    if (mPointerController != NULL) {
        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
@@ -3761,6 +3772,8 @@ void TouchInputMapper::sync(nsecs_t when) {
                mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
                        mCurrentCookedPointerData.idToIndex,
                        mCurrentCookedPointerData.touchingIdBits);
            } else if (mDeviceMode == DEVICE_MODE_NAVIGATION) {
                dispatchNavigationAssist(when, policyFlags);
            }

            dispatchHoverExit(when, policyFlags);
@@ -5482,6 +5495,44 @@ void TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
    dispatchPointerSimple(when, policyFlags, false, false);
}

void TouchInputMapper::dispatchNavigationAssist(nsecs_t when, uint32_t policyFlags) {
    if (mCurrentCookedPointerData.touchingIdBits.count() == 1) {
        if (mLastCookedPointerData.touchingIdBits.isEmpty()) {
            // First pointer down.
            uint32_t id = mCurrentCookedPointerData.touchingIdBits.firstMarkedBit();
            const PointerCoords& coords = mCurrentCookedPointerData.pointerCoordsForId(id);
            if (coords.getY() >= mNavigationAssistStartY) {
                // Start tracking the possible assist swipe.
                mNavigation.activeAssistId = id;
                return;
            }
        } else if (mNavigation.activeAssistId >= 0
                && mCurrentCookedPointerData.touchingIdBits.hasBit(mNavigation.activeAssistId)) {
            const PointerCoords& coords = mCurrentCookedPointerData.pointerCoordsForId(
                    mNavigation.activeAssistId);
            if (coords.getY() > mNavigationAssistEndY) {
                // Swipe is still in progress.
                return;
            }

            // Detected assist swipe.
            int32_t metaState = mContext->getGlobalMetaState();
            NotifyKeyArgs downArgs(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD,
                    policyFlags | POLICY_FLAG_VIRTUAL,
                    AKEY_EVENT_ACTION_DOWN, 0, AKEYCODE_ASSIST, 0, metaState, when);
            getListener()->notifyKey(&downArgs);

            NotifyKeyArgs upArgs(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD,
                    policyFlags | POLICY_FLAG_VIRTUAL,
                    AKEY_EVENT_ACTION_UP, 0, AKEYCODE_ASSIST, 0, metaState, when);
            getListener()->notifyKey(&upArgs);
        }
    }

    // Cancel the assist swipe.
    mNavigation.activeAssistId = -1;
}

void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
        const PointerProperties* properties, const PointerCoords* coords,
+20 −0
Original line number Diff line number Diff line
@@ -791,6 +791,10 @@ struct CookedPointerData {
    void clear();
    void copyFrom(const CookedPointerData& other);

    inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
        return pointerCoords[idToIndex[id]];
    }

    inline bool isHovering(uint32_t pointerIndex) {
        return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
    }
@@ -1180,6 +1184,7 @@ protected:
        DEVICE_MODE_DISABLED, // input is disabled
        DEVICE_MODE_DIRECT, // direct mapping (touchscreen)
        DEVICE_MODE_UNSCALED, // unscaled mapping (touchpad)
        DEVICE_MODE_NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
        DEVICE_MODE_POINTER, // pointer mapping (pointer)
    };
    DeviceMode mDeviceMode;
@@ -1432,6 +1437,10 @@ private:
    // The maximum swipe width.
    float mPointerGestureMaxSwipeWidth;

    // The start and end Y thresholds for invoking the assist navigation swipe.
    float mNavigationAssistStartY;
    float mNavigationAssistEndY;

    struct PointerDistanceHeapElement {
        uint32_t currentPointerIndex : 8;
        uint32_t lastPointerIndex : 8;
@@ -1606,6 +1615,15 @@ private:
        }
    } mPointerSimple;

    struct Navigation {
        // The id of a pointer that is tracking a possible assist swipe.
        int32_t activeAssistId; // -1 if none

        void reset() {
            activeAssistId = -1;
        }
    } mNavigation;

    // The pointer and scroll velocity controls.
    VelocityControl mPointerVelocityControl;
    VelocityControl mWheelXVelocityControl;
@@ -1641,6 +1659,8 @@ private:
            bool down, bool hovering);
    void abortPointerSimple(nsecs_t when, uint32_t policyFlags);

    void dispatchNavigationAssist(nsecs_t when, uint32_t policyFlags);

    // Dispatches a motion event.
    // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
    // method will take care of setting the index and transmuting the action to DOWN or UP