diff options
| -rw-r--r-- | include/input/InputWindow.h | 8 | ||||
| -rw-r--r-- | libs/gui/tests/EndToEndNativeInputTest.cpp | 2 | ||||
| -rw-r--r-- | libs/input/InputWindow.cpp | 19 | ||||
| -rw-r--r-- | libs/input/tests/InputWindow_test.cpp | 15 | ||||
| -rw-r--r-- | services/inputflinger/InputDispatcher.cpp | 41 | ||||
| -rw-r--r-- | services/inputflinger/InputDispatcher.h | 9 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 2 |
8 files changed, 61 insertions, 39 deletions
diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h index 9e3d334f7f..6164aa6f09 100644 --- a/include/input/InputWindow.h +++ b/include/input/InputWindow.h @@ -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; } /** diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 2f165c4131..7b727047d1 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -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; diff --git a/libs/input/InputWindow.cpp b/libs/input/InputWindow.cpp index f82437e1bf..96646dc6f8 100644 --- a/libs/input/InputWindow.cpp +++ b/libs/input/InputWindow.cpp @@ -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 diff --git a/libs/input/tests/InputWindow_test.cpp b/libs/input/tests/InputWindow_test.cpp index 39ad26e8c1..ea98f8a302 100644 --- a/libs/input/tests/InputWindow_test.cpp +++ b/libs/input/tests/InputWindow_test.cpp @@ -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); diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp index 0c9e04bc18..e0082a5a95 100644 --- a/services/inputflinger/InputDispatcher.cpp +++ b/services/inputflinger/InputDispatcher.cpp @@ -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; } diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h index 5016082958..38c7b45c59 100644 --- a/services/inputflinger/InputDispatcher.h +++ b/services/inputflinger/InputDispatcher.h @@ -29,6 +29,7 @@ #include <utils/Looper.h> #include <utils/BitSet.h> #include <cutils/atomic.h> +#include <unordered_map> #include <stddef.h> #include <unistd.h> @@ -916,6 +917,13 @@ private: // All registered connections mapped by channel file descriptor. KeyedVector<int, sp<Connection> > mConnectionsByFd; + struct IBinderHash { + std::size_t operator()(const sp<IBinder>& b) const { + return std::hash<IBinder *>{}(b.get()); + } + }; + std::unordered_map<sp<IBinder>, sp<InputChannel>, IBinderHash> mInputChannelsByToken; + ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel); // Input channels that will receive a copy of all input events sent to the provided display. @@ -979,6 +987,7 @@ private: // Get window handles by display, return an empty vector if not found. Vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const; sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const; + sp<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const; bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const; // Focus tracking for keys, trackball, etc. diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index e860db59c4..26adcdd8a9 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -338,7 +338,6 @@ protected: const std::string name, int32_t displayId) : mDispatcher(dispatcher), mName(name), mDisplayId(displayId) { InputChannel::openInputChannelPair(name, mServerChannel, mClientChannel); - mConsumer = new InputConsumer(mClientChannel); } @@ -352,6 +351,7 @@ protected: sp<InputDispatcher> mDispatcher; sp<InputChannel> mServerChannel, mClientChannel; + sp<IBinder> mToken; InputConsumer *mConsumer; PreallocatedInputEventFactory mEventFactory; @@ -374,7 +374,7 @@ public: } virtual bool updateInfo() { - mInfo.inputChannel = mServerChannel; + mInfo.token = mServerChannel->getToken(); mInfo.name = mName; mInfo.layoutParamsFlags = 0; mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index d9ec44a03e..3c37cf80be 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2082,7 +2082,7 @@ InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) { } bool Layer::hasInput() const { - return mDrawingState.inputInfo.inputChannel != nullptr; + return mDrawingState.inputInfo.token != nullptr; } // --------------------------------------------------------------------------- |