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

Commit 9c9f1a3b authored by Jeff Brown's avatar Jeff Brown
Browse files

Track input state when transferring touch focus.

Copies the input state to the destination window and sends synthesic
cancelation events to the source window.

Change-Id: Ia75820b0d756ed5d6cd22dce7830251ac85141ed
parent e20c9e02
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -757,6 +757,9 @@ private:
        // Clears the current state.
        void clear();

        // Copies pointer-related parts of the input state to another instance.
        void copyPointerStateTo(InputState& other) const;

    private:
        struct KeyMemento {
            int32_t deviceId;
+30 −0
Original line number Diff line number Diff line
@@ -2668,6 +2668,18 @@ bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
            return false;
        }

        ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
        ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
        if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
            sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
            sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);

            fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
            synthesizeCancelationEventsForConnectionLocked(fromConnection,
                    InputState::CANCEL_POINTER_EVENTS,
                    "transferring touch focus from this window to another window");
        }

#if DEBUG_FOCUS
        logDispatchStateLocked();
#endif
@@ -3404,6 +3416,24 @@ void InputDispatcher::InputState::clear() {
    mMotionMementos.clear();
}

void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
    for (size_t i = 0; i < mMotionMementos.size(); i++) {
        const MotionMemento& memento = mMotionMementos.itemAt(i);
        if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
            for (size_t j = 0; j < other.mMotionMementos.size(); ) {
                const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
                if (memento.deviceId == otherMemento.deviceId
                        && memento.source == otherMemento.source) {
                    other.mMotionMementos.removeAt(j);
                } else {
                    j += 1;
                }
            }
            other.mMotionMementos.push(memento);
        }
    }
}

bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
        CancelationOptions options) {
    switch (options) {
+0 −2
Original line number Diff line number Diff line
@@ -1233,7 +1233,6 @@ static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
        jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
    if (checkInputManagerUnitialized(env)) {
        LOGD("input manager uninitialized; bailing");
        return false;
    }

@@ -1243,7 +1242,6 @@ static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env
            android_view_InputChannel_getInputChannel(env, toChannelObj);

    if (fromChannel == NULL || toChannel == NULL) {
        LOGD("bailing because from=%p to=%p", fromChannel, toChannel);
        return false;
    }