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

Commit 5c8a0261 authored by Robert Carr's avatar Robert Carr
Browse files

Replace InputWindowInfo#inputChannel with an IBinder token.

The IBinder token is now being used as the UUID for InputWindows.
We can pass it around without the channel to avoid unnecessary FD
parcelling, duping, and other juggling.

Test: Existing tests pass.
Bug: 80101428
Bug: 113136004
Bug: 111440400
Change-Id: I8eba3fa05f249b7dfcb5c3d9817241cbfe9ab76c
parent 1c4c5599
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -117,7 +117,7 @@ struct InputWindowInfo {
        INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
        INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
    };
    };


    sp<InputChannel> inputChannel;
    sp<IBinder> token;
    std::string name;
    std::string name;
    int32_t layoutParamsFlags;
    int32_t layoutParamsFlags;
    int32_t layoutParamsType;
    int32_t layoutParamsType;
@@ -174,14 +174,14 @@ public:
        return &mInfo;
        return &mInfo;
    }
    }


    sp<InputChannel> getInputChannel() const;
    sp<IBinder> getToken() const;


    inline std::string getName() const {
    inline std::string getName() const {
        return mInfo.inputChannel ? mInfo.name : "<invalid>";
        return mInfo.token ? mInfo.name : "<invalid>";
    }
    }


    inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const {
    inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const {
        return mInfo.inputChannel? mInfo.dispatchingTimeout : defaultValue;
        return mInfo.token ? mInfo.dispatchingTimeout : defaultValue;
    }
    }


    /**
    /**
+1 −1
Original line number Original line Diff line number Diff line
@@ -135,7 +135,7 @@ private:
    }
    }


    void populateInputInfo(int width, int height) {
    void populateInputInfo(int width, int height) {
        mInputInfo.inputChannel = mServerChannel;
        mInputInfo.token = mServerChannel->getToken();
        mInputInfo.name = "Test info";
        mInputInfo.name = "Test info";
        mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
        mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
        mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION;
        mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION;
+9 −10
Original line number Original line Diff line number Diff line
@@ -65,12 +65,12 @@ bool InputWindowInfo::overlaps(const InputWindowInfo* other) const {
}
}


status_t InputWindowInfo::write(Parcel& output) const {
status_t InputWindowInfo::write(Parcel& output) const {
    if (inputChannel == nullptr) {
    if (token == nullptr) {
        output.writeInt32(0);
        output.writeInt32(0);
        return OK;
        return OK;
    }
    }
    output.writeInt32(1);
    output.writeInt32(1);
    status_t s = inputChannel->write(output);
    status_t s = output.writeStrongBinder(token);
    if (s != OK) return s;
    if (s != OK) return s;


    output.writeString8(String8(name.c_str()));
    output.writeString8(String8(name.c_str()));
@@ -102,15 +102,14 @@ InputWindowInfo InputWindowInfo::read(const Parcel& from) {


    if (from.readInt32() == 0) {
    if (from.readInt32() == 0) {
        return ret;
        return ret;

    }
    }
    sp<InputChannel> inputChannel = new InputChannel();

    status_t s = inputChannel->read(from);
    sp<IBinder> token = from.readStrongBinder();
    if (s != OK) {
    if (token == nullptr) {
        return ret;
        return ret;
    }
    }


    ret.inputChannel = inputChannel;
    ret.token = token;
    ret.name = from.readString8().c_str();
    ret.name = from.readString8().c_str();
    ret.layoutParamsFlags = from.readInt32();
    ret.layoutParamsFlags = from.readInt32();
    ret.layoutParamsType = from.readInt32();
    ret.layoutParamsType = from.readInt32();
@@ -149,11 +148,11 @@ InputWindowHandle::~InputWindowHandle() {
}
}


void InputWindowHandle::releaseChannel() {
void InputWindowHandle::releaseChannel() {
    mInfo.inputChannel.clear();
    mInfo.token.clear();
}
}


sp<InputChannel> InputWindowHandle::getInputChannel() const {
sp<IBinder> InputWindowHandle::getToken() const {
    return mInfo.inputChannel;
    return mInfo.token;
}
}


} // namespace android
} // namespace android
+6 −9
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


#include <gtest/gtest.h>
#include <gtest/gtest.h>


#include <binder/Binder.h>
#include <binder/Parcel.h>
#include <binder/Parcel.h>


#include <input/InputWindow.h>
#include <input/InputWindow.h>
@@ -24,24 +25,20 @@
namespace android {
namespace android {
namespace test {
namespace test {


TEST(InputWindowInfo, ParcellingWithoutChannel) {
TEST(InputWindowInfo, ParcellingWithoutToken) {
    InputWindowInfo i;
    InputWindowInfo i;
    i.inputChannel = nullptr;
    i.token = nullptr;


    Parcel p;
    Parcel p;
    ASSERT_EQ(OK, i.write(p));
    ASSERT_EQ(OK, i.write(p));
    p.setDataPosition(0);
    p.setDataPosition(0);
    InputWindowInfo i2 = InputWindowInfo::read(p);
    InputWindowInfo i2 = InputWindowInfo::read(p);
    ASSERT_TRUE(i2.inputChannel == nullptr);
    ASSERT_TRUE(i2.token == nullptr);
}
}


TEST(InputWindowInfo, Parcelling) {
TEST(InputWindowInfo, Parcelling) {
    sp<InputChannel> channel, junkChannel;
    status_t result = InputChannel::openInputChannelPair("name", channel, junkChannel);
    ASSERT_EQ(OK, result) << "openInputChannelPair should have returned valid channels";

    InputWindowInfo i;
    InputWindowInfo i;
    i.inputChannel = channel;
    i.token = new BBinder();
    i.name = "Foobar";
    i.name = "Foobar";
    i.layoutParamsFlags = 7;
    i.layoutParamsFlags = 7;
    i.layoutParamsType = 39;
    i.layoutParamsType = 39;
@@ -67,7 +64,7 @@ TEST(InputWindowInfo, Parcelling) {


    p.setDataPosition(0);
    p.setDataPosition(0);
    InputWindowInfo i2 = InputWindowInfo::read(p);
    InputWindowInfo i2 = InputWindowInfo::read(p);
    ASSERT_EQ(i.inputChannel->getName(), i2.inputChannel->getName());
    ASSERT_EQ(i.token, i2.token);
    ASSERT_EQ(i.name, i2.name);
    ASSERT_EQ(i.name, i2.name);
    ASSERT_EQ(i.layoutParamsFlags, i2.layoutParamsFlags);
    ASSERT_EQ(i.layoutParamsFlags, i2.layoutParamsFlags);
    ASSERT_EQ(i.layoutParamsType, i2.layoutParamsType);
    ASSERT_EQ(i.layoutParamsType, i2.layoutParamsType);
+29 −12
Original line number Original line Diff line number Diff line
@@ -819,7 +819,7 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
            sp<InputWindowHandle> focusedWindowHandle =
            sp<InputWindowHandle> focusedWindowHandle =
                    getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
                    getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
            if (focusedWindowHandle != nullptr) {
            if (focusedWindowHandle != nullptr) {
                commandEntry->inputChannel = focusedWindowHandle->getInputChannel();
                commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
            }
            }
            commandEntry->keyEntry = entry;
            commandEntry->keyEntry = entry;
            entry->refCount += 1;
            entry->refCount += 1;
@@ -1666,7 +1666,7 @@ void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowH


    const InputWindowInfo* windowInfo = windowHandle->getInfo();
    const InputWindowInfo* windowInfo = windowHandle->getInfo();
    InputTarget& target = inputTargets.editTop();
    InputTarget& target = inputTargets.editTop();
    target.inputChannel = windowInfo->inputChannel;
    target.inputChannel = getInputChannelLocked(windowHandle->getToken());
    target.flags = targetFlags;
    target.flags = targetFlags;
    target.xOffset = - windowInfo->frameLeft;
    target.xOffset = - windowInfo->frameLeft;
    target.yOffset = - windowInfo->frameTop;
    target.yOffset = - windowInfo->frameTop;
@@ -1773,7 +1773,8 @@ std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentT
    }
    }


    // If the window's connection is not registered then keep waiting.
    // If the window's connection is not registered then keep waiting.
    ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
    ssize_t connectionIndex = getConnectionIndexLocked(
            getInputChannelLocked(windowHandle->getToken()));
    if (connectionIndex < 0) {
    if (connectionIndex < 0) {
        return StringPrintf("Waiting because the %s window's input channel is not "
        return StringPrintf("Waiting because the %s window's input channel is not "
                "registered with the input dispatcher.  The window may be in the process "
                "registered with the input dispatcher.  The window may be in the process "
@@ -3004,7 +3005,7 @@ sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
        size_t numWindows = windowHandles.size();
        size_t numWindows = windowHandles.size();
        for (size_t i = 0; i < numWindows; i++) {
        for (size_t i = 0; i < numWindows; i++) {
            const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
            const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
            if (windowHandle->getInputChannel() == inputChannel) {
            if (windowHandle->getToken() == inputChannel->getToken()) {
                return windowHandle;
                return windowHandle;
            }
            }
        }
        }
@@ -3018,8 +3019,8 @@ bool InputDispatcher::hasWindowHandleLocked(
        const Vector<sp<InputWindowHandle>> windowHandles = it.second;
        const Vector<sp<InputWindowHandle>> windowHandles = it.second;
        size_t numWindows = windowHandles.size();
        size_t numWindows = windowHandles.size();
        for (size_t i = 0; i < numWindows; i++) {
        for (size_t i = 0; i < numWindows; i++) {
            if (windowHandles.itemAt(i)->getInputChannel()->getToken()
            if (windowHandles.itemAt(i)->getToken()
                    == windowHandle->getInputChannel()->getToken()) {
                    == windowHandle->getToken()) {
                if (windowHandle->getInfo()->displayId != it.first) {
                if (windowHandle->getInfo()->displayId != it.first) {
                    ALOGE("Found window %s in display %" PRId32
                    ALOGE("Found window %s in display %" PRId32
                            ", but it should belong to display %" PRId32,
                            ", but it should belong to display %" PRId32,
@@ -3033,6 +3034,14 @@ bool InputDispatcher::hasWindowHandleLocked(
    return false;
    return false;
}
}


sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
    size_t count = mInputChannelsByToken.count(token);
    if (count == 0) {
        return nullptr;
    }
    return mInputChannelsByToken.at(token);
}

/**
/**
 * Called from InputManagerService, update window handle list by displayId that can receive input.
 * Called from InputManagerService, update window handle list by displayId that can receive input.
 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
@@ -3061,7 +3070,9 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input
            size_t numWindows = inputWindowHandles.size();
            size_t numWindows = inputWindowHandles.size();
            for (size_t i = 0; i < numWindows; i++) {
            for (size_t i = 0; i < numWindows; i++) {
                const sp<InputWindowHandle>& windowHandle = inputWindowHandles.itemAt(i);
                const sp<InputWindowHandle>& windowHandle = inputWindowHandles.itemAt(i);
                if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == nullptr) {
                if (!windowHandle->updateInfo() || getInputChannelLocked(windowHandle->getToken()) == nullptr) {
                    ALOGE("Window handle %s has no registered input channel",
                            windowHandle->getName().c_str());
                    continue;
                    continue;
                }
                }


@@ -3097,7 +3108,8 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input
                ALOGD("Focus left window: %s in display %" PRId32,
                ALOGD("Focus left window: %s in display %" PRId32,
                        oldFocusedWindowHandle->getName().c_str(), displayId);
                        oldFocusedWindowHandle->getName().c_str(), displayId);
#endif
#endif
                sp<InputChannel> focusedInputChannel = oldFocusedWindowHandle->getInputChannel();
                sp<InputChannel> focusedInputChannel = getInputChannelLocked(
                        oldFocusedWindowHandle->getToken());
                if (focusedInputChannel != nullptr) {
                if (focusedInputChannel != nullptr) {
                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
                            "focus left window");
                            "focus left window");
@@ -3126,7 +3138,7 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input
                            touchedWindow.windowHandle->getName().c_str(), displayId);
                            touchedWindow.windowHandle->getName().c_str(), displayId);
#endif
#endif
                    sp<InputChannel> touchedInputChannel =
                    sp<InputChannel> touchedInputChannel =
                            touchedWindow.windowHandle->getInputChannel();
                            getInputChannelLocked(touchedWindow.windowHandle->getToken());
                    if (touchedInputChannel != nullptr) {
                    if (touchedInputChannel != nullptr) {
                        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
                        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
                                "touched window was removed");
                                "touched window was removed");
@@ -3214,7 +3226,8 @@ void InputDispatcher::setFocusedDisplay(int32_t displayId) {
            sp<InputWindowHandle> oldFocusedWindowHandle =
            sp<InputWindowHandle> oldFocusedWindowHandle =
                    getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
                    getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
            if (oldFocusedWindowHandle != nullptr) {
            if (oldFocusedWindowHandle != nullptr) {
                sp<InputChannel> inputChannel = oldFocusedWindowHandle->getInputChannel();
                sp<InputChannel> inputChannel =
                    getInputChannelLocked(oldFocusedWindowHandle->getToken());
                if (inputChannel != nullptr) {
                if (inputChannel != nullptr) {
                    CancelationOptions options(
                    CancelationOptions options(
                            CancelationOptions::CANCEL_DISPLAY_UNSPECIFIED_EVENTS,
                            CancelationOptions::CANCEL_DISPLAY_UNSPECIFIED_EVENTS,
@@ -3667,6 +3680,7 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan


        int fd = inputChannel->getFd();
        int fd = inputChannel->getFd();
        mConnectionsByFd.add(fd, connection);
        mConnectionsByFd.add(fd, connection);
        mInputChannelsByToken[inputChannel->getToken()] = inputChannel;


        // Store monitor channel by displayId.
        // Store monitor channel by displayId.
        if (monitor) {
        if (monitor) {
@@ -3715,6 +3729,8 @@ status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& i
    sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
    sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
    mConnectionsByFd.removeItemsAt(connectionIndex);
    mConnectionsByFd.removeItemsAt(connectionIndex);


    mInputChannelsByToken.erase(inputChannel->getToken());

    if (connection->monitor) {
    if (connection->monitor) {
        removeMonitorChannelLocked(inputChannel);
        removeMonitorChannelLocked(inputChannel);
    }
    }
@@ -3812,7 +3828,8 @@ void InputDispatcher::onANRLocked(
    CommandEntry* commandEntry = postCommandLocked(
    CommandEntry* commandEntry = postCommandLocked(
            & InputDispatcher::doNotifyANRLockedInterruptible);
            & InputDispatcher::doNotifyANRLockedInterruptible);
    commandEntry->inputApplicationHandle = applicationHandle;
    commandEntry->inputApplicationHandle = applicationHandle;
    commandEntry->inputChannel = windowHandle != nullptr ? windowHandle->getInputChannel() : nullptr;
    commandEntry->inputChannel = windowHandle != nullptr ?
            getInputChannelLocked(windowHandle->getToken()) : nullptr;
    commandEntry->reason = reason;
    commandEntry->reason = reason;
}
}


@@ -4847,7 +4864,7 @@ void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& wind


void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
    for (size_t i = 0; i < windows.size(); i++) {
    for (size_t i = 0; i < windows.size(); i++) {
        if (windows.itemAt(i).windowHandle->getInputChannel()->getToken() == token) {
        if (windows.itemAt(i).windowHandle->getToken() == token) {
            windows.removeAt(i);
            windows.removeAt(i);
            return;
            return;
        }
        }
Loading