diff options
| -rw-r--r-- | include/input/InputTransport.h | 47 | ||||
| -rw-r--r-- | libs/gui/tests/EndToEndNativeInputTest.cpp | 3 | ||||
| -rw-r--r-- | libs/input/InputTransport.cpp | 47 | ||||
| -rw-r--r-- | libs/input/tests/InputChannel_test.cpp | 11 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 40 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 4 |
6 files changed, 78 insertions, 74 deletions
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index 1822e4a0db..94d90ad30b 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -167,11 +167,15 @@ protected: virtual ~InputChannel(); public: - static sp<InputChannel> create(const std::string& name, android::base::unique_fd fd); + static sp<InputChannel> create(const std::string& name, android::base::unique_fd fd, + sp<IBinder> token); - /* Creates a pair of input channels. + /** + * Create a pair of input channels. + * The two returned input channels are equivalent, and are labeled as "server" and "client" + * for convenience. The two input channels share the same token. * - * Returns OK on success. + * Return OK on success. */ static status_t openInputChannelPair(const std::string& name, sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel); @@ -179,46 +183,57 @@ public: inline std::string getName() const { return mName; } inline int getFd() const { return mFd.get(); } - /* Sends a message to the other endpoint. + /* Send a message to the other endpoint. * * If the channel is full then the message is guaranteed not to have been sent at all. * Try again after the consumer has sent a finished signal indicating that it has * consumed some of the pending messages from the channel. * - * Returns OK on success. - * Returns WOULD_BLOCK if the channel is full. - * Returns DEAD_OBJECT if the channel's peer has been closed. + * Return OK on success. + * Return WOULD_BLOCK if the channel is full. + * Return DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ status_t sendMessage(const InputMessage* msg); - /* Receives a message sent by the other endpoint. + /* Receive a message sent by the other endpoint. * * If there is no message present, try again after poll() indicates that the fd * is readable. * - * Returns OK on success. - * Returns WOULD_BLOCK if there is no message present. - * Returns DEAD_OBJECT if the channel's peer has been closed. + * Return OK on success. + * Return WOULD_BLOCK if there is no message present. + * Return DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ status_t receiveMessage(InputMessage* msg); - /* Returns a new object that has a duplicate of this channel's fd. */ + /* Return a new object that has a duplicate of this channel's fd. */ sp<InputChannel> dup() const; status_t write(Parcel& out) const; static sp<InputChannel> read(const Parcel& from); - sp<IBinder> getToken() const; - void setToken(const sp<IBinder>& token); + /** + * The connection token is used to identify the input connection, i.e. + * the pair of input channels that were created simultaneously. Input channels + * are always created in pairs, and the token can be used to find the server-side + * input channel from the client-side input channel, and vice versa. + * + * Do not use connection token to check equality of a specific input channel object + * to another, because two different (client and server) input channels will share the + * same connection token. + * + * Return the token that identifies this connection. + */ + sp<IBinder> getConnectionToken() const; private: - InputChannel(const std::string& name, android::base::unique_fd fd); + InputChannel(const std::string& name, android::base::unique_fd fd, sp<IBinder> token); std::string mName; android::base::unique_fd mFd; - sp<IBinder> mToken = nullptr; + sp<IBinder> mToken; }; /* diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 03b9cd75db..8d36ba7b70 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -69,7 +69,6 @@ public: mSurfaceControl = sc; InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel); - mServerChannel->setToken(new BBinder()); mInputFlinger = getInputFlinger(); mInputFlinger->registerInputChannel(mServerChannel); @@ -165,7 +164,7 @@ private: } void populateInputInfo(int width, int height) { - mInputInfo.token = mServerChannel->getToken(); + mInputInfo.token = mServerChannel->getConnectionToken(); mInputInfo.name = "Test info"; mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL; mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION; diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index c4f7fe0bf2..a5dd3c0544 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -11,7 +11,7 @@ #define DEBUG_CHANNEL_MESSAGES 0 // Log debug messages whenever InputChannel objects are created/destroyed -#define DEBUG_CHANNEL_LIFECYCLE 0 +static constexpr bool DEBUG_CHANNEL_LIFECYCLE = false; // Log debug messages about transport actions #define DEBUG_TRANSPORT_ACTIONS 0 @@ -225,28 +225,28 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const { // --- InputChannel --- -sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd) { +sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd, + sp<IBinder> token) { const int result = fcntl(fd, F_SETFL, O_NONBLOCK); if (result != 0) { LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(), strerror(errno)); return nullptr; } - return new InputChannel(name, std::move(fd)); + return new InputChannel(name, std::move(fd), token); } -InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd) - : mName(name), mFd(std::move(fd)) { -#if DEBUG_CHANNEL_LIFECYCLE - ALOGD("Input channel constructed: name='%s', fd=%d", - mName.c_str(), fd); -#endif +InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd, sp<IBinder> token) + : mName(name), mFd(std::move(fd)), mToken(token) { + if (DEBUG_CHANNEL_LIFECYCLE) { + ALOGD("Input channel constructed: name='%s', fd=%d", mName.c_str(), mFd.get()); + } } InputChannel::~InputChannel() { -#if DEBUG_CHANNEL_LIFECYCLE - ALOGD("Input channel destroyed: name='%s', fd=%d", mName.c_str(), mFd.get()); -#endif + if (DEBUG_CHANNEL_LIFECYCLE) { + ALOGD("Input channel destroyed: name='%s', fd=%d", mName.c_str(), mFd.get()); + } } status_t InputChannel::openInputChannelPair(const std::string& name, @@ -267,13 +267,15 @@ status_t InputChannel::openInputChannelPair(const std::string& name, setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); + sp<IBinder> token = new BBinder(); + std::string serverChannelName = name + " (server)"; android::base::unique_fd serverFd(sockets[0]); - outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd)); + outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd), token); std::string clientChannelName = name + " (client)"; android::base::unique_fd clientFd(sockets[1]); - outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd)); + outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd), token); return OK; } @@ -369,7 +371,7 @@ sp<InputChannel> InputChannel::dup() const { getName().c_str()); return nullptr; } - return InputChannel::create(mName, std::move(newFd)); + return InputChannel::create(mName, std::move(newFd), mToken); } status_t InputChannel::write(Parcel& out) const { @@ -396,24 +398,13 @@ sp<InputChannel> InputChannel::read(const Parcel& from) { return nullptr; } - sp<InputChannel> channel = InputChannel::create(name, std::move(rawFd)); - if (channel != nullptr) { - channel->setToken(token); - } - return channel; + return InputChannel::create(name, std::move(rawFd), token); } -sp<IBinder> InputChannel::getToken() const { +sp<IBinder> InputChannel::getConnectionToken() const { return mToken; } -void InputChannel::setToken(const sp<IBinder>& token) { - if (mToken != nullptr) { - ALOGE("Assigning InputChannel (%s) a second handle?", mName.c_str()); - } - mToken = token; -} - // --- InputPublisher --- InputPublisher::InputPublisher(const sp<InputChannel>& channel) : diff --git a/libs/input/tests/InputChannel_test.cpp b/libs/input/tests/InputChannel_test.cpp index 7c331e132d..ada275d014 100644 --- a/libs/input/tests/InputChannel_test.cpp +++ b/libs/input/tests/InputChannel_test.cpp @@ -46,7 +46,8 @@ TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptor android::base::unique_fd sendFd(pipe.sendFd); - sp<InputChannel> inputChannel = InputChannel::create("channel name", std::move(sendFd)); + sp<InputChannel> inputChannel = + InputChannel::create("channel name", std::move(sendFd), new BBinder()); EXPECT_NE(inputChannel, nullptr) << "channel should be successfully created"; EXPECT_STREQ("channel name", inputChannel->getName().c_str()) @@ -59,13 +60,11 @@ TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptor TEST_F(InputChannelTest, SetAndGetToken) { Pipe pipe; + sp<IBinder> token = new BBinder(); sp<InputChannel> channel = - InputChannel::create("test channel", android::base::unique_fd(pipe.sendFd)); - EXPECT_EQ(channel->getToken(), nullptr); + InputChannel::create("test channel", android::base::unique_fd(pipe.sendFd), token); - sp<IBinder> token = new BBinder(); - channel->setToken(token); - EXPECT_EQ(token, channel->getToken()); + EXPECT_EQ(token, channel->getConnectionToken()); } TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) { diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 24b27b9f15..58a5b3c8d3 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -1038,7 +1038,8 @@ void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* event pokeUserActivityLocked(*eventEntry); for (const InputTarget& inputTarget : inputTargets) { - sp<Connection> connection = getConnectionLocked(inputTarget.inputChannel->getToken()); + sp<Connection> connection = + getConnectionLocked(inputTarget.inputChannel->getConnectionToken()); if (connection != nullptr) { prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget); } else { @@ -2142,7 +2143,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio } dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction, - inputTarget->inputChannel->getToken()); + inputTarget->inputChannel->getConnectionToken()); break; } @@ -2472,7 +2473,7 @@ void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked( void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked( const sp<InputChannel>& channel, const CancelationOptions& options) { - sp<Connection> connection = getConnectionLocked(channel->getToken()); + sp<Connection> connection = getConnectionLocked(channel->getConnectionToken()); if (connection == nullptr) { return; } @@ -2514,7 +2515,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( InputTarget target; sp<InputWindowHandle> windowHandle = - getWindowHandleLocked(connection->inputChannel->getToken()); + getWindowHandleLocked(connection->inputChannel->getConnectionToken()); if (windowHandle != nullptr) { const InputWindowInfo* windowInfo = windowHandle->getInfo(); target.xOffset = -windowInfo->frameLeft; @@ -3866,7 +3867,7 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan { // acquire lock std::scoped_lock _l(mLock); - sp<Connection> existingConnection = getConnectionLocked(inputChannel->getToken()); + sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken()); if (existingConnection != nullptr) { ALOGW("Attempted to register already registered input channel '%s'", inputChannel->getName().c_str()); @@ -3877,7 +3878,7 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan int fd = inputChannel->getFd(); mConnectionsByFd[fd] = connection; - mInputChannelsByToken[inputChannel->getToken()] = inputChannel; + mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel; mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this); } // release lock @@ -3897,7 +3898,7 @@ status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChan return BAD_VALUE; } - if (inputChannel->getToken() == nullptr) { + if (inputChannel->getConnectionToken() == nullptr) { ALOGW("Attempted to register input monitor without an identifying token."); return BAD_VALUE; } @@ -3906,7 +3907,7 @@ status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChan const int fd = inputChannel->getFd(); mConnectionsByFd[fd] = connection; - mInputChannelsByToken[inputChannel->getToken()] = inputChannel; + mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel; auto& monitorsByDisplay = isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay; @@ -3941,7 +3942,7 @@ status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputCh status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel, bool notify) { - sp<Connection> connection = getConnectionLocked(inputChannel->getToken()); + sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken()); if (connection == nullptr) { ALOGW("Attempted to unregister already unregistered input channel '%s'", inputChannel->getName().c_str()); @@ -3950,7 +3951,7 @@ status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& i [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection); ALOG_ASSERT(removed); - mInputChannelsByToken.erase(inputChannel->getToken()); + mInputChannelsByToken.erase(inputChannel->getConnectionToken()); if (connection->monitor) { removeMonitorChannelLocked(inputChannel); @@ -4010,7 +4011,7 @@ status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) { TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex); std::optional<int32_t> foundDeviceId; for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) { - if (touchedMonitor.monitor.inputChannel->getToken() == token) { + if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) { foundDeviceId = state.deviceId; } } @@ -4041,7 +4042,7 @@ std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked( for (const auto& it : mGestureMonitorsByDisplay) { const std::vector<Monitor>& monitors = it.second; for (const Monitor& monitor : monitors) { - if (monitor.inputChannel->getToken() == token) { + if (monitor.inputChannel->getConnectionToken() == token) { return it.first; } } @@ -4056,7 +4057,7 @@ sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConn for (const auto& pair : mConnectionsByFd) { const sp<Connection>& connection = pair.second; - if (connection->inputChannel->getToken() == inputConnectionToken) { + if (connection->inputChannel->getConnectionToken() == inputConnectionToken) { return connection; } } @@ -4149,7 +4150,7 @@ void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry if (connection->status != Connection::STATUS_ZOMBIE) { mLock.unlock(); - mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken()); + mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken()); mLock.lock(); } @@ -4165,7 +4166,7 @@ void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* comm void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) { sp<IBinder> token = - commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr; + commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr; mLock.unlock(); nsecs_t newTimeout = @@ -4186,7 +4187,7 @@ void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible( android::base::Timer t; sp<IBinder> token = commandEntry->inputChannel != nullptr - ? commandEntry->inputChannel->getToken() + ? commandEntry->inputChannel->getConnectionToken() : nullptr; nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags); if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) { @@ -4305,7 +4306,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& con mLock.unlock(); - mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(), &event, + mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event, keyEntry->policyFlags, &event); mLock.lock(); @@ -4346,8 +4347,9 @@ bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& con mLock.unlock(); - bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(), &event, - keyEntry->policyFlags, &event); + bool fallback = + mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), + &event, keyEntry->policyFlags, &event); mLock.lock(); diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 7d69854868..b706a749fe 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -470,7 +470,6 @@ public: const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) : FakeInputReceiver(dispatcher, name, displayId), mFocused(false), mFrame(Rect(0, 0, WIDTH, HEIGHT)), mLayoutParamFlags(0) { - mServerChannel->setToken(new BBinder()); mDispatcher->registerInputChannel(mServerChannel); inputApplicationHandle->updateInfo(); @@ -478,7 +477,7 @@ public: } virtual bool updateInfo() { - mInfo.token = mServerChannel ? mServerChannel->getToken() : nullptr; + mInfo.token = mServerChannel ? mServerChannel->getConnectionToken() : nullptr; mInfo.name = mName; mInfo.layoutParamsFlags = mLayoutParamFlags; mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION; @@ -859,7 +858,6 @@ public: FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId, bool isGestureMonitor = false) : FakeInputReceiver(dispatcher, name, displayId) { - mServerChannel->setToken(new BBinder()); mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor); } }; |