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

Commit adefc3e2 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Unregister input channel by token

An input channel is uniquely identified by its token. Once the input
channel exists, you can unregister it simply using its token.

There's no need to pass back the entire input channel, including its id,
to input dispatcher. We will look for the server-side input channel
using the token anyways.

Bug: 167947395
Test: atest libinput_tests
Change-Id: I009da372bd6cc897b019a66e9c3bbed78cc91223
parent 24e1e94c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -156,7 +156,7 @@ public:
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
    }

    ~InputSurface() { mInputFlinger->unregisterInputChannel(*mServerChannel); }
    ~InputSurface() { mInputFlinger->unregisterInputChannel(mServerChannel->getConnectionToken()); }

    void doTransaction(std::function<void(SurfaceComposerClient::Transaction&,
                    const sp<SurfaceControl>&)> transactionBody) {
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ interface IInputFlinger
    oneway void setInputWindows(in InputWindowInfo[] inputHandles,
            in @nullable ISetInputWindowsListener setInputWindowsListener);
    void registerInputChannel(in InputChannel channel);
    void unregisterInputChannel(in InputChannel channel);
    void unregisterInputChannel(in IBinder connectionToken);
    /**
     * Sets focus to the window identified by the token. This must be called
     * after updating any input window handles.
+2 −2
Original line number Diff line number Diff line
@@ -132,8 +132,8 @@ binder::Status InputManager::registerInputChannel(const InputChannel& channel) {
    return binder::Status::ok();
}

binder::Status InputManager::unregisterInputChannel(const InputChannel& channel) {
    mDispatcher->unregisterInputChannel(channel);
binder::Status InputManager::unregisterInputChannel(const sp<IBinder>& connectionToken) {
    mDispatcher->unregisterInputChannel(connectionToken);
    return binder::Status::ok();
}

+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ public:
            const sp<ISetInputWindowsListener>& setInputWindowsListener) override;

    binder::Status registerInputChannel(const InputChannel& channel) override;
    binder::Status unregisterInputChannel(const InputChannel& channel) override;
    binder::Status unregisterInputChannel(const sp<IBinder>& connectionToken) override;
    binder::Status setFocusedWindow(const FocusRequest&) override;

private:
+15 −21
Original line number Diff line number Diff line
@@ -379,7 +379,7 @@ InputDispatcher::~InputDispatcher() {

    while (!mConnectionsByFd.empty()) {
        sp<Connection> connection = mConnectionsByFd.begin()->second;
        unregisterInputChannel(*connection->inputChannel);
        unregisterInputChannel(connection->inputChannel->getConnectionToken());
    }
}

@@ -2793,7 +2793,7 @@ int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
        }

        // Unregister the channel.
        d->unregisterInputChannelLocked(*connection->inputChannel, notify);
        d->unregisterInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
        return 0; // remove the callback
    }             // release lock
}
@@ -3313,7 +3313,6 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec
          "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
          event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
#endif

    nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();

    policyFlags |= POLICY_FLAG_INJECTED;
@@ -4429,15 +4428,11 @@ status_t InputDispatcher::registerInputMonitor(const std::shared_ptr<InputChanne
    return OK;
}

status_t InputDispatcher::unregisterInputChannel(const InputChannel& inputChannel) {
#if DEBUG_REGISTRATION
    ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel.getName().c_str());
#endif

status_t InputDispatcher::unregisterInputChannel(const sp<IBinder>& connectionToken) {
    { // acquire lock
        std::scoped_lock _l(mLock);

        status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
        status_t status = unregisterInputChannelLocked(connectionToken, false /*notify*/);
        if (status) {
            return status;
        }
@@ -4449,23 +4444,22 @@ status_t InputDispatcher::unregisterInputChannel(const InputChannel& inputChanne
    return OK;
}

status_t InputDispatcher::unregisterInputChannelLocked(const InputChannel& inputChannel,
status_t InputDispatcher::unregisterInputChannelLocked(const sp<IBinder>& connectionToken,
                                                       bool notify) {
    sp<Connection> connection = getConnectionLocked(inputChannel.getConnectionToken());
    sp<Connection> connection = getConnectionLocked(connectionToken);
    if (connection == nullptr) {
        ALOGW("Attempted to unregister already unregistered input channel '%s'",
              inputChannel.getName().c_str());
        ALOGW("Attempted to unregister already unregistered input channel");
        return BAD_VALUE;
    }

    removeConnectionLocked(connection);
    mInputChannelsByToken.erase(inputChannel.getConnectionToken());
    mInputChannelsByToken.erase(connectionToken);

    if (connection->monitor) {
        removeMonitorChannelLocked(inputChannel);
        removeMonitorChannelLocked(connectionToken);
    }

    mLooper->removeFd(inputChannel.getFd());
    mLooper->removeFd(connection->inputChannel->getFd());

    nsecs_t currentTime = now();
    abortBrokenDispatchCycleLocked(currentTime, connection, notify);
@@ -4474,19 +4468,19 @@ status_t InputDispatcher::unregisterInputChannelLocked(const InputChannel& input
    return OK;
}

void InputDispatcher::removeMonitorChannelLocked(const InputChannel& inputChannel) {
    removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
    removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
    removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
    removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
}

void InputDispatcher::removeMonitorChannelLocked(
        const InputChannel& inputChannel,
        const sp<IBinder>& connectionToken,
        std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
    for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
        std::vector<Monitor>& monitors = it->second;
        const size_t numMonitors = monitors.size();
        for (size_t i = 0; i < numMonitors; i++) {
            if (*monitors[i].inputChannel == inputChannel) {
            if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
                monitors.erase(monitors.begin() + i);
                break;
            }
Loading