Loading include/ui/InputDispatcher.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -554,6 +554,8 @@ private: // All registered connections mapped by receive pipe file descriptor. // All registered connections mapped by receive pipe file descriptor. KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd; KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd; ssize_t getConnectionIndex(const sp<InputChannel>& inputChannel); // Active connections are connections that have a non-empty outbound queue. // Active connections are connections that have a non-empty outbound queue. // We don't use a ref-counted pointer here because we explicitly abort connections // We don't use a ref-counted pointer here because we explicitly abort connections // during unregistration which causes the connection's outbound queue to be cleared // during unregistration which causes the connection's outbound queue to be cleared Loading libs/ui/InputDispatcher.cpp +20 −12 Original line number Original line Diff line number Diff line Loading @@ -433,8 +433,7 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi for (size_t i = 0; i < mCurrentInputTargets.size(); i++) { for (size_t i = 0; i < mCurrentInputTargets.size(); i++) { const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i); const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i); ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey( ssize_t connectionIndex = getConnectionIndex(inputTarget.inputChannel); inputTarget.inputChannel->getReceivePipeFd()); if (connectionIndex >= 0) { if (connectionIndex >= 0) { sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget, prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget, Loading Loading @@ -1367,12 +1366,10 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan LOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().string()); LOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().string()); #endif #endif int receiveFd; { // acquire lock { // acquire lock AutoMutex _l(mLock); AutoMutex _l(mLock); receiveFd = inputChannel->getReceivePipeFd(); if (getConnectionIndex(inputChannel) >= 0) { if (mConnectionsByReceiveFd.indexOfKey(receiveFd) >= 0) { LOGW("Attempted to register already registered input channel '%s'", LOGW("Attempted to register already registered input channel '%s'", inputChannel->getName().string()); inputChannel->getName().string()); return BAD_VALUE; return BAD_VALUE; Loading @@ -1386,12 +1383,13 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan return status; return status; } } int32_t receiveFd = inputChannel->getReceivePipeFd(); mConnectionsByReceiveFd.add(receiveFd, connection); mConnectionsByReceiveFd.add(receiveFd, connection); mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this); runCommandsLockedInterruptible(); runCommandsLockedInterruptible(); } // release lock } // release lock mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this); return OK; return OK; } } Loading @@ -1400,12 +1398,10 @@ status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputCh LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string()); LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string()); #endif #endif int32_t receiveFd; { // acquire lock { // acquire lock AutoMutex _l(mLock); AutoMutex _l(mLock); receiveFd = inputChannel->getReceivePipeFd(); ssize_t connectionIndex = getConnectionIndex(inputChannel); ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd); if (connectionIndex < 0) { if (connectionIndex < 0) { LOGW("Attempted to unregister already unregistered input channel '%s'", LOGW("Attempted to unregister already unregistered input channel '%s'", inputChannel->getName().string()); inputChannel->getName().string()); Loading @@ -1417,20 +1413,32 @@ status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputCh connection->status = Connection::STATUS_ZOMBIE; connection->status = Connection::STATUS_ZOMBIE; mPollLoop->removeCallback(inputChannel->getReceivePipeFd()); nsecs_t currentTime = now(); nsecs_t currentTime = now(); abortDispatchCycleLocked(currentTime, connection, true /*broken*/); abortDispatchCycleLocked(currentTime, connection, true /*broken*/); runCommandsLockedInterruptible(); runCommandsLockedInterruptible(); } // release lock } // release lock mPollLoop->removeCallback(receiveFd); // Wake the poll loop because removing the connection may have changed the current // Wake the poll loop because removing the connection may have changed the current // synchronization state. // synchronization state. mPollLoop->wake(); mPollLoop->wake(); return OK; return OK; } } ssize_t InputDispatcher::getConnectionIndex(const sp<InputChannel>& inputChannel) { ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd()); if (connectionIndex >= 0) { sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); if (connection->inputChannel.get() == inputChannel.get()) { return connectionIndex; } } return -1; } void InputDispatcher::activateConnectionLocked(Connection* connection) { void InputDispatcher::activateConnectionLocked(Connection* connection) { for (size_t i = 0; i < mActiveConnections.size(); i++) { for (size_t i = 0; i < mActiveConnections.size(); i++) { if (mActiveConnections.itemAt(i) == connection) { if (mActiveConnections.itemAt(i) == connection) { Loading Loading
include/ui/InputDispatcher.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -554,6 +554,8 @@ private: // All registered connections mapped by receive pipe file descriptor. // All registered connections mapped by receive pipe file descriptor. KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd; KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd; ssize_t getConnectionIndex(const sp<InputChannel>& inputChannel); // Active connections are connections that have a non-empty outbound queue. // Active connections are connections that have a non-empty outbound queue. // We don't use a ref-counted pointer here because we explicitly abort connections // We don't use a ref-counted pointer here because we explicitly abort connections // during unregistration which causes the connection's outbound queue to be cleared // during unregistration which causes the connection's outbound queue to be cleared Loading
libs/ui/InputDispatcher.cpp +20 −12 Original line number Original line Diff line number Diff line Loading @@ -433,8 +433,7 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi for (size_t i = 0; i < mCurrentInputTargets.size(); i++) { for (size_t i = 0; i < mCurrentInputTargets.size(); i++) { const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i); const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i); ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey( ssize_t connectionIndex = getConnectionIndex(inputTarget.inputChannel); inputTarget.inputChannel->getReceivePipeFd()); if (connectionIndex >= 0) { if (connectionIndex >= 0) { sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget, prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget, Loading Loading @@ -1367,12 +1366,10 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan LOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().string()); LOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().string()); #endif #endif int receiveFd; { // acquire lock { // acquire lock AutoMutex _l(mLock); AutoMutex _l(mLock); receiveFd = inputChannel->getReceivePipeFd(); if (getConnectionIndex(inputChannel) >= 0) { if (mConnectionsByReceiveFd.indexOfKey(receiveFd) >= 0) { LOGW("Attempted to register already registered input channel '%s'", LOGW("Attempted to register already registered input channel '%s'", inputChannel->getName().string()); inputChannel->getName().string()); return BAD_VALUE; return BAD_VALUE; Loading @@ -1386,12 +1383,13 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan return status; return status; } } int32_t receiveFd = inputChannel->getReceivePipeFd(); mConnectionsByReceiveFd.add(receiveFd, connection); mConnectionsByReceiveFd.add(receiveFd, connection); mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this); runCommandsLockedInterruptible(); runCommandsLockedInterruptible(); } // release lock } // release lock mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this); return OK; return OK; } } Loading @@ -1400,12 +1398,10 @@ status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputCh LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string()); LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string()); #endif #endif int32_t receiveFd; { // acquire lock { // acquire lock AutoMutex _l(mLock); AutoMutex _l(mLock); receiveFd = inputChannel->getReceivePipeFd(); ssize_t connectionIndex = getConnectionIndex(inputChannel); ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd); if (connectionIndex < 0) { if (connectionIndex < 0) { LOGW("Attempted to unregister already unregistered input channel '%s'", LOGW("Attempted to unregister already unregistered input channel '%s'", inputChannel->getName().string()); inputChannel->getName().string()); Loading @@ -1417,20 +1413,32 @@ status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputCh connection->status = Connection::STATUS_ZOMBIE; connection->status = Connection::STATUS_ZOMBIE; mPollLoop->removeCallback(inputChannel->getReceivePipeFd()); nsecs_t currentTime = now(); nsecs_t currentTime = now(); abortDispatchCycleLocked(currentTime, connection, true /*broken*/); abortDispatchCycleLocked(currentTime, connection, true /*broken*/); runCommandsLockedInterruptible(); runCommandsLockedInterruptible(); } // release lock } // release lock mPollLoop->removeCallback(receiveFd); // Wake the poll loop because removing the connection may have changed the current // Wake the poll loop because removing the connection may have changed the current // synchronization state. // synchronization state. mPollLoop->wake(); mPollLoop->wake(); return OK; return OK; } } ssize_t InputDispatcher::getConnectionIndex(const sp<InputChannel>& inputChannel) { ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd()); if (connectionIndex >= 0) { sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); if (connection->inputChannel.get() == inputChannel.get()) { return connectionIndex; } } return -1; } void InputDispatcher::activateConnectionLocked(Connection* connection) { void InputDispatcher::activateConnectionLocked(Connection* connection) { for (size_t i = 0; i < mActiveConnections.size(); i++) { for (size_t i = 0; i < mActiveConnections.size(); i++) { if (mActiveConnections.itemAt(i) == connection) { if (mActiveConnections.itemAt(i) == connection) { Loading