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 Diff line number Diff line
@@ -117,7 +117,7 @@ struct InputWindowInfo {
        INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
    };

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

    sp<InputChannel> getInputChannel() const;
    sp<IBinder> getToken() 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 {
        return mInfo.inputChannel? mInfo.dispatchingTimeout : defaultValue;
        return mInfo.token ? mInfo.dispatchingTimeout : defaultValue;
    }

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

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

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

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

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

    }
    sp<InputChannel> inputChannel = new InputChannel();
    status_t s = inputChannel->read(from);
    if (s != OK) {

    sp<IBinder> token = from.readStrongBinder();
    if (token == nullptr) {
        return ret;
    }

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

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

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

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

#include <gtest/gtest.h>

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

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

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

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

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

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

    const InputWindowInfo* windowInfo = windowHandle->getInfo();
    InputTarget& target = inputTargets.editTop();
    target.inputChannel = windowInfo->inputChannel;
    target.inputChannel = getInputChannelLocked(windowHandle->getToken());
    target.flags = targetFlags;
    target.xOffset = - windowInfo->frameLeft;
    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.
    ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
    ssize_t connectionIndex = getConnectionIndexLocked(
            getInputChannelLocked(windowHandle->getToken()));
    if (connectionIndex < 0) {
        return StringPrintf("Waiting because the %s window's input channel is not "
                "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();
        for (size_t i = 0; i < numWindows; i++) {
            const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
            if (windowHandle->getInputChannel() == inputChannel) {
            if (windowHandle->getToken() == inputChannel->getToken()) {
                return windowHandle;
            }
        }
@@ -3018,8 +3019,8 @@ bool InputDispatcher::hasWindowHandleLocked(
        const Vector<sp<InputWindowHandle>> windowHandles = it.second;
        size_t numWindows = windowHandles.size();
        for (size_t i = 0; i < numWindows; i++) {
            if (windowHandles.itemAt(i)->getInputChannel()->getToken()
                    == windowHandle->getInputChannel()->getToken()) {
            if (windowHandles.itemAt(i)->getToken()
                    == windowHandle->getToken()) {
                if (windowHandle->getInfo()->displayId != it.first) {
                    ALOGE("Found window %s in display %" PRId32
                            ", but it should belong to display %" PRId32,
@@ -3033,6 +3034,14 @@ bool InputDispatcher::hasWindowHandleLocked(
    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.
 * 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();
            for (size_t i = 0; i < numWindows; 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;
                }

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

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

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

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

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

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

void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
    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);
            return;
        }
Loading