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

Commit 21237a0c authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Fix drag and drop (2/3)"

parents e8f9a6f3 fbe5d9c4
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ public:
    DECLARE_META_INTERFACE(InputFlinger)

    virtual void setInputWindows(const Vector<InputWindowInfo>& inputHandles) = 0;

    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;
    virtual void registerInputChannel(const sp<InputChannel>& channel) = 0;
    virtual void unregisterInputChannel(const sp<InputChannel>& channel) = 0;
};
@@ -50,7 +50,8 @@ public:
    enum {
        SET_INPUT_WINDOWS_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
        REGISTER_INPUT_CHANNEL_TRANSACTION,
        UNREGISTER_INPUT_CHANNEL_TRANSACTION
        UNREGISTER_INPUT_CHANNEL_TRANSACTION,
        TRANSFER_TOUCH_FOCUS
    };

    virtual status_t onTransact(uint32_t code, const Parcel& data,
+50 −0
Original line number Diff line number Diff line
@@ -133,6 +133,27 @@ public:
        EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
    }

    void expectMotionEvent(int motionEventType, int x, int y) {
        InputEvent *ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(ev->getType(), AINPUT_EVENT_TYPE_MOTION);
        MotionEvent *mev = static_cast<MotionEvent *>(ev);
        EXPECT_EQ(motionEventType, mev->getAction());
        EXPECT_EQ(x, mev->getX(0));
        EXPECT_EQ(y, mev->getY(0));
    }

    void expectNoMotionEvent(int motionEventType) {
        InputEvent *ev = consumeEvent();
        if (ev == nullptr || ev->getType() != AINPUT_EVENT_TYPE_MOTION) {
            // Didn't find an event or a motion event so assume action didn't occur.
            return;
        }

        MotionEvent *mev = static_cast<MotionEvent *>(ev);
        EXPECT_NE(motionEventType, mev->getAction());
    }

    ~InputSurface() {
        mInputFlinger->unregisterInputChannel(mServerChannel);
    }
@@ -255,6 +276,15 @@ void injectTap(int x, int y) {
    }
}

void injectMotionEvent(std::string event, int x, int y) {
    char *buf1, *buf2;
    asprintf(&buf1, "%d", x);
    asprintf(&buf2, "%d", y);
    if (fork() == 0) {
        execlp("input", "input", "motionevent", event.c_str(), buf1, buf2, NULL);
    }
}

TEST_F(InputSurfacesTest, can_receive_input) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);
@@ -439,5 +469,25 @@ TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
    injectTap(11, 11);
    bgSurface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, transfer_touch_focus) {
    std::unique_ptr<InputSurface> fromSurface = makeSurface(100, 100);

    fromSurface->showAt(10, 10);
    injectMotionEvent("DOWN", 11, 11);
    fromSurface->expectMotionEvent(AMOTION_EVENT_ACTION_DOWN, 1, 1);

    std::unique_ptr<InputSurface> toSurface = makeSurface(100, 100);
    toSurface->showAt(10, 10);

    sp<IBinder> fromToken = fromSurface->mServerChannel->getToken();
    sp<IBinder> toToken = toSurface->mServerChannel->getToken();
    SurfaceComposerClient::Transaction t;
    t.transferTouchFocus(fromToken, toToken).apply(true);

    injectMotionEvent("UP", 11, 11);
    toSurface->expectMotionEvent(AMOTION_EVENT_ACTION_UP, 1, 1);
    fromSurface->expectNoMotionEvent(AMOTION_EVENT_ACTION_UP);
}
}
}
+17 −0
Original line number Diff line number Diff line
@@ -42,6 +42,16 @@ public:
                IBinder::FLAG_ONEWAY);
    }

    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
        Parcel data, reply;
        data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());

        data.writeStrongBinder(fromToken);
        data.writeStrongBinder(toToken);
        remote()->transact(BnInputFlinger::TRANSFER_TOUCH_FOCUS, data, &reply,
                IBinder::FLAG_ONEWAY);
    }

    virtual void registerInputChannel(const sp<InputChannel>& channel) {
        Parcel data, reply;
        data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
@@ -90,6 +100,13 @@ status_t BnInputFlinger::onTransact(
        unregisterInputChannel(channel);
        break;
    }
    case TRANSFER_TOUCH_FOCUS: {
        CHECK_INTERFACE(IInputFlinger, data, reply);
        sp<IBinder> fromToken = data.readStrongBinder();
        sp<IBinder> toToken = data.readStrongBinder();
        transferTouchFocus(fromToken, toToken);
        break;
    }
    default:
        return BBinder::onTransact(code, data, reply, flags);
    }
+22 −15
Original line number Diff line number Diff line
@@ -2386,7 +2386,8 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
            }

            InputTarget target;
            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
                    connection->inputChannel->getToken());
            if (windowHandle != nullptr) {
                const InputWindowInfo* windowInfo = windowHandle->getInfo();
                target.xOffset = -windowInfo->frameLeft;
@@ -3024,13 +3025,13 @@ Vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(int32_t di
}

sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
        const sp<InputChannel>& inputChannel) const {
        const sp<IBinder>& windowHandleToken) const {
    for (auto& it : mWindowHandlesByDisplay) {
        const Vector<sp<InputWindowHandle>> windowHandles = it.second;
        size_t numWindows = windowHandles.size();
        for (size_t i = 0; i < numWindows; i++) {
            const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
            if (windowHandle->getToken() == inputChannel->getToken()) {
            if (windowHandle->getToken() == windowHandleToken) {
                return windowHandle;
            }
        }
@@ -3375,27 +3376,30 @@ void InputDispatcher::setInputFilterEnabled(bool enabled) {

bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
        const sp<InputChannel>& toChannel) {
    return transferTouchFocus(fromChannel->getToken(), toChannel->getToken());
}

bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
    if (fromToken == toToken) {
#if DEBUG_FOCUS
    ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
            fromChannel->getName().c_str(), toChannel->getName().c_str());
        ALOGD("Trivial transfer to same window.");
#endif
        return true;
    }

    { // acquire lock
        AutoMutex _l(mLock);

        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
        if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
#if DEBUG_FOCUS
            ALOGD("Cannot transfer focus because from or to window not found.");
        ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
            fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
#endif
        if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
            ALOGW("Cannot transfer focus because from or to window not found.");
            return false;
        }
        if (fromWindowHandle == toWindowHandle) {
#if DEBUG_FOCUS
            ALOGD("Trivial transfer to same window.");
#endif
            return true;
        }
        if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
#if DEBUG_FOCUS
            ALOGD("Cannot transfer focus because windows are on different displays.");
@@ -3433,6 +3437,9 @@ Found:
            return false;
        }


        sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
        sp<InputChannel> toChannel = getInputChannelLocked(toToken);
        ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
        ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
        if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
+5 −3
Original line number Diff line number Diff line
@@ -343,11 +343,12 @@ public:
     */
    virtual void setInputFilterEnabled(bool enabled) = 0;

    /* Transfers touch focus from the window associated with one channel to the
     * window associated with the other channel.
    /* Transfers touch focus from one window to another window.
     *
     * Returns true on success.  False if the window did not actually have touch focus.
     */
    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;

    virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
            const sp<InputChannel>& toChannel) = 0;

@@ -414,6 +415,7 @@ public:
    virtual void setInputDispatchMode(bool enabled, bool frozen);
    virtual void setInputFilterEnabled(bool enabled);

    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
    virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
            const sp<InputChannel>& toChannel);

@@ -995,7 +997,7 @@ private:
    std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay;
    // Get window handles by display, return an empty vector if not found.
    Vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const;
    sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
    sp<InputWindowHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken) const;
    sp<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const;
    bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;

Loading