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

Commit 4eed0f8f authored by Michael Wright's avatar Michael Wright Committed by Android (Google) Code Review
Browse files

Merge "Synthesize events for pressure and button changes." into mnc-dev

parents 09d561db 43fd19fd
Loading
Loading
Loading
Loading
+39 −19
Original line number Original line Diff line number Diff line
@@ -73,6 +73,13 @@ static const size_t MAX_SLOTS = 32;
// external stylus.
// external stylus.
static const nsecs_t EXTERNAL_STYLUS_DATA_TIMEOUT = ms2ns(72);
static const nsecs_t EXTERNAL_STYLUS_DATA_TIMEOUT = ms2ns(72);


// Maximum amount of time to wait on touch data before pushing out new pressure data.
static const nsecs_t TOUCH_DATA_TIMEOUT = ms2ns(20);

// Artificial latency on synthetic events created from stylus data without corresponding touch
// data.
static const nsecs_t STYLUS_DATA_LATENCY = ms2ns(10);

// --- Static Functions ---
// --- Static Functions ---


template<typename T>
template<typename T>
@@ -2827,7 +2834,7 @@ void TouchInputMapper::dump(String8& dump) {
            toString(mExternalStylusConnected));
            toString(mExternalStylusConnected));
    dump.appendFormat(INDENT4 "External Stylus ID: %" PRId64 "\n", mExternalStylusId);
    dump.appendFormat(INDENT4 "External Stylus ID: %" PRId64 "\n", mExternalStylusId);
    dump.appendFormat(INDENT4 "External Stylus Data Timeout: %" PRId64 "\n",
    dump.appendFormat(INDENT4 "External Stylus Data Timeout: %" PRId64 "\n",
            mExternalStylusDataTimeout);
            mExternalStylusFusionTimeout);
    dump.append(INDENT3 "External Stylus State:\n");
    dump.append(INDENT3 "External Stylus State:\n");
    dumpStylusState(dump, mExternalStylusState);
    dumpStylusState(dump, mExternalStylusState);


@@ -3836,10 +3843,15 @@ void TouchInputMapper::reset(nsecs_t when) {
void TouchInputMapper::resetExternalStylus() {
void TouchInputMapper::resetExternalStylus() {
    mExternalStylusState.clear();
    mExternalStylusState.clear();
    mExternalStylusId = -1;
    mExternalStylusId = -1;
    mExternalStylusDataTimeout = LLONG_MAX;
    mExternalStylusFusionTimeout = LLONG_MAX;
    mExternalStylusDataPending = false;
    mExternalStylusDataPending = false;
}
}


void TouchInputMapper::clearStylusDataPendingFlags() {
    mExternalStylusDataPending = false;
    mExternalStylusFusionTimeout = LLONG_MAX;
}

void TouchInputMapper::process(const RawEvent* rawEvent) {
void TouchInputMapper::process(const RawEvent* rawEvent) {
    mCursorButtonAccumulator.process(rawEvent);
    mCursorButtonAccumulator.process(rawEvent);
    mCursorScrollAccumulator.process(rawEvent);
    mCursorScrollAccumulator.process(rawEvent);
@@ -3915,19 +3927,30 @@ void TouchInputMapper::processRawTouches(bool timeout) {
        }
        }


        // All ready to go.
        // All ready to go.
        mExternalStylusDataPending = false;
        clearStylusDataPendingFlags();
        mCurrentRawState.copyFrom(next);
        mCurrentRawState.copyFrom(next);
        if (mCurrentRawState.when < mLastRawState.when) {
            mCurrentRawState.when = mLastRawState.when;
        }
        cookAndDispatch(mCurrentRawState.when);
        cookAndDispatch(mCurrentRawState.when);
    }
    }
    if (count != 0) {
    if (count != 0) {
        mRawStatesPending.removeItemsAt(0, count);
        mRawStatesPending.removeItemsAt(0, count);
    }
    }


    // TODO: If we still have pending stylus data that hasn't been mapped to a touch yet
    // then set a timeout to synthesize a new touch event with the new data.  Otherwise
    // we will lose button and pressure information while the touch is stationary.
    if (mExternalStylusDataPending) {
    if (mExternalStylusDataPending) {
        ALOGD("STYLUS TODO: Wiggle wiggle wiggle.");
        if (timeout) {
            nsecs_t when = mExternalStylusFusionTimeout - STYLUS_DATA_LATENCY;
            clearStylusDataPendingFlags();
            mCurrentRawState.copyFrom(mLastRawState);
#if DEBUG_STYLUS_FUSION
            ALOGD("Timeout expired, synthesizing event with new stylus data");
#endif
            cookAndDispatch(when);
        } else if (mExternalStylusFusionTimeout == LLONG_MAX) {
            mExternalStylusFusionTimeout = mExternalStylusState.when + TOUCH_DATA_TIMEOUT;
            getContext()->requestTimeoutAtTime(mExternalStylusFusionTimeout);
        }
    }
    }
}
}


@@ -4086,15 +4109,14 @@ bool TouchInputMapper::assignExternalStylusId(const RawState& state, bool timeou
#endif
#endif
            resetExternalStylus();
            resetExternalStylus();
        } else {
        } else {
            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            if (mExternalStylusFusionTimeout == LLONG_MAX) {
            if (mExternalStylusDataTimeout == LLONG_MAX) {
                mExternalStylusFusionTimeout = state.when + EXTERNAL_STYLUS_DATA_TIMEOUT;
                mExternalStylusDataTimeout = now + EXTERNAL_STYLUS_DATA_TIMEOUT;
            }
            }
#if DEBUG_STYLUS_FUSION
#if DEBUG_STYLUS_FUSION
            ALOGD("No stylus data but stylus is connected, requesting timeout "
            ALOGD("No stylus data but stylus is connected, requesting timeout "
                    "(%" PRId64 "ms)", mExternalStylusDataTimeout);
                    "(%" PRId64 "ms)", mExternalStylusFusionTimeout);
#endif
#endif
            getContext()->requestTimeoutAtTime(mExternalStylusDataTimeout);
            getContext()->requestTimeoutAtTime(mExternalStylusFusionTimeout);
            return true;
            return true;
        }
        }
    }
    }
@@ -4117,22 +4139,20 @@ void TouchInputMapper::timeoutExpired(nsecs_t when) {
            dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
            dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
        }
        }
    } else if (mDeviceMode == DEVICE_MODE_DIRECT) {
    } else if (mDeviceMode == DEVICE_MODE_DIRECT) {
        if (mExternalStylusDataTimeout < when) {
        if (mExternalStylusFusionTimeout < when) {
            mExternalStylusDataTimeout = LLONG_MAX;
            processRawTouches(true /*timeout*/);
            processRawTouches(true /*timeout*/);
        } else if (mExternalStylusDataTimeout != LLONG_MAX) {
        } else if (mExternalStylusFusionTimeout != LLONG_MAX) {
            getContext()->requestTimeoutAtTime(mExternalStylusDataTimeout);
            getContext()->requestTimeoutAtTime(mExternalStylusFusionTimeout);
        }
        }
    }
    }
}
}


void TouchInputMapper::updateExternalStylusState(const StylusState& state) {
void TouchInputMapper::updateExternalStylusState(const StylusState& state) {
    mExternalStylusState.copyFrom(state);
    mExternalStylusState.copyFrom(state);
    if (mExternalStylusId != -1 || mExternalStylusDataTimeout != LLONG_MAX) {
    if (mExternalStylusId != -1 || mExternalStylusFusionTimeout != LLONG_MAX) {
        // We're either in the middle of a fused stream of data or we're waiting on data before
        // We're either in the middle of a fused stream of data or we're waiting on data before
        // dispatching the initial down, so go ahead and dispatch now that we have fresh stylus
        // dispatching the initial down, so go ahead and dispatch now that we have fresh stylus
        // data.
        // data.
        mExternalStylusDataTimeout = LLONG_MAX;
        mExternalStylusDataPending = true;
        mExternalStylusDataPending = true;
        processRawTouches(false /*timeout*/);
        processRawTouches(false /*timeout*/);
    }
    }
@@ -4310,7 +4330,7 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
        // Dispatch move events if any of the remaining pointers moved from their old locations.
        // Dispatch move events if any of the remaining pointers moved from their old locations.
        // Although applications receive new locations as part of individual pointer up
        // Although applications receive new locations as part of individual pointer up
        // events, they do not generally handle them except when presented in a move event.
        // events, they do not generally handle them except when presented in a move event.
        if (moveNeeded) {
        if (moveNeeded && !moveIdBits.isEmpty()) {
            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
            dispatchMotion(when, policyFlags, mSource,
            dispatchMotion(when, policyFlags, mSource,
                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
+2 −1
Original line number Original line Diff line number Diff line
@@ -1456,7 +1456,7 @@ protected:
    // State provided by an external stylus
    // State provided by an external stylus
    StylusState mExternalStylusState;
    StylusState mExternalStylusState;
    int64_t mExternalStylusId;
    int64_t mExternalStylusId;
    nsecs_t mExternalStylusDataTimeout;
    nsecs_t mExternalStylusFusionTimeout;
    bool mExternalStylusDataPending;
    bool mExternalStylusDataPending;


    // True if we sent a HOVER_ENTER event.
    // True if we sent a HOVER_ENTER event.
@@ -1781,6 +1781,7 @@ private:
    VelocityControl mWheelYVelocityControl;
    VelocityControl mWheelYVelocityControl;


    void resetExternalStylus();
    void resetExternalStylus();
    void clearStylusDataPendingFlags();


    void sync(nsecs_t when);
    void sync(nsecs_t when);