summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/input/InputWindow.h8
-rw-r--r--libs/gui/tests/EndToEndNativeInputTest.cpp2
-rw-r--r--libs/input/InputWindow.cpp19
-rw-r--r--libs/input/tests/InputWindow_test.cpp15
-rw-r--r--services/inputflinger/InputDispatcher.cpp41
-rw-r--r--services/inputflinger/InputDispatcher.h9
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp4
-rw-r--r--services/surfaceflinger/Layer.cpp2
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;
}
// ---------------------------------------------------------------------------