Merge changes from topic "sfinput3"
* changes:
InputFlinger: Receive setInputWindows over IPC
InputDispatcher: Look up channel by token.
InputDispatcher: Track InputChannels by IBinder token.
Add setInputWindowInfo to SurfaceComposerClient::Transaction
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h
index 11bb721..1ef8986 100644
--- a/include/input/IInputFlinger.h
+++ b/include/input/IInputFlinger.h
@@ -22,6 +22,9 @@
#include <binder/IInterface.h>
+#include <utils/Vector.h>
+#include <input/InputWindow.h>
+
namespace android {
/*
@@ -31,6 +34,8 @@
class IInputFlinger : public IInterface {
public:
DECLARE_META_INTERFACE(InputFlinger)
+
+ virtual void setInputWindows(const Vector<InputWindowInfo>& inputHandles) = 0;
};
@@ -40,7 +45,7 @@
class BnInputFlinger : public BnInterface<IInputFlinger> {
public:
enum {
- DO_SOMETHING_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+ SET_INPUT_WINDOWS_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/include/input/Input.h b/include/input/Input.h
index 819a89f..d35354b 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -17,6 +17,8 @@
#ifndef _LIBINPUT_INPUT_H
#define _LIBINPUT_INPUT_H
+#pragma GCC system_header
+
/**
* Native input event structures.
*/
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 4782c9b..d906db3 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -17,6 +17,8 @@
#ifndef _LIBINPUT_INPUT_TRANSPORT_H
#define _LIBINPUT_INPUT_TRANSPORT_H
+#pragma GCC system_header
+
/**
* Native input transport.
*
@@ -29,6 +31,7 @@
#include <string>
+#include <binder/IBinder.h>
#include <input/Input.h>
#include <utils/Errors.h>
#include <utils/Timers.h>
@@ -188,11 +191,16 @@
status_t write(Parcel& out) const;
status_t read(const Parcel& from);
+ sp<IBinder> getToken() const;
+ void setToken(const sp<IBinder>& token);
+
private:
void setFd(int fd);
std::string mName;
int mFd = -1;
+
+ sp<IBinder> mToken = nullptr;
};
/*
diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h
index 918b9e1..9e3d334 100644
--- a/include/input/InputWindow.h
+++ b/include/input/InputWindow.h
@@ -33,6 +33,9 @@
* Describes the properties of a window that can receive input.
*/
struct InputWindowInfo {
+ InputWindowInfo() = default;
+ InputWindowInfo(const Parcel& from);
+
// Window flags from WindowManager.LayoutParams
enum {
FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001,
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 7677c3a..127fcd6 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -135,6 +135,7 @@
"libutils",
"libnativewindow",
"liblog",
+ "libinput",
"libhidlbase",
"libhidltransport",
"android.hidl.token@1.0-utils",
@@ -146,7 +147,7 @@
// bufferhub is not used when building libgui for vendors
target: {
vendor: {
- cflags: ["-DNO_BUFFERHUB"],
+ cflags: ["-DNO_BUFFERHUB", "-DNO_INPUT"],
exclude_srcs: [
"BufferHubConsumer.cpp",
"BufferHubProducer.cpp",
@@ -155,6 +156,7 @@
"libbufferhub",
"libbufferhubqueue",
"libpdx_default_transport",
+ "libinput"
],
},
},
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 7b71b39..9f30060 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -50,6 +50,9 @@
output.writeFloat(color.r);
output.writeFloat(color.g);
output.writeFloat(color.b);
+#ifndef NO_INPUT
+ inputInfo.write(output);
+#endif
output.write(transparentRegion);
output.writeUint32(transform);
output.writeBool(transformToDisplayInverse);
@@ -120,6 +123,11 @@
color.r = input.readFloat();
color.g = input.readFloat();
color.b = input.readFloat();
+
+#ifndef NO_INPUT
+ inputInfo = InputWindowInfo::read(input);
+#endif
+
input.read(transparentRegion);
transform = input.readUint32();
transformToDisplayInverse = input.readBool();
@@ -343,6 +351,13 @@
listenerCallbacks = other.listenerCallbacks;
}
+#ifndef NO_INPUT
+ if (other.what & eInputInfoChanged) {
+ what |= eInputInfoChanged;
+ inputInfo = other.inputInfo;
+ }
+#endif
+
if ((other.what & what) != other.what) {
ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
"other.what=0x%X what=0x%X",
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index e10bda4..87c6f27 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -42,6 +42,10 @@
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
+#ifndef NO_INPUT
+#include <input/InputWindow.h>
+#endif
+
#include <private/gui/ComposerService.h>
namespace android {
@@ -759,6 +763,21 @@
return *this;
}
+#ifndef NO_INPUT
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo(
+ const sp<SurfaceControl>& sc,
+ const InputWindowInfo& info) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+ s->inputInfo = info;
+ s->what |= layer_state_t::eInputInfoChanged;
+ return *this;
+}
+#endif
+
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroySurface(
const sp<SurfaceControl>& sc) {
layer_state_t* s = getLayerState(sc);
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index ddbac7b..cdb2309 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -25,6 +25,11 @@
#include <gui/IGraphicBufferProducer.h>
#include <gui/ITransactionCompletedListener.h>
#include <math/mat4.h>
+
+#ifndef NO_INPUT
+#include <input/InputWindow.h>
+#endif
+
#include <math/vec3.h>
#include <ui/GraphicTypes.h>
#include <ui/Rect.h>
@@ -76,6 +81,7 @@
eSidebandStreamChanged = 0x08000000,
eColorTransformChanged = 0x10000000,
eListenerCallbacksChanged = 0x20000000,
+ eInputInfoChanged = 0x40000000,
};
layer_state_t()
@@ -158,6 +164,9 @@
mat4 colorTransform;
std::vector<ListenerCallbacks> listenerCallbacks;
+#ifndef NO_INPUT
+ InputWindowInfo inputInfo;
+#endif
};
struct ComposerState {
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 1cafb77..10c27b1 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -330,6 +330,10 @@
// freezing the total geometry of a surface until a resize is completed.
Transaction& setGeometryAppliesWithResize(const sp<SurfaceControl>& sc);
+#ifndef NO_INPUT
+ Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
+#endif
+
Transaction& destroySurface(const sp<SurfaceControl>& sc);
// Set a color transform matrix on the given layer on the built-in display.
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 72558a6..8cb8649 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -43,12 +43,12 @@
target: {
android: {
srcs: [
- "IInputFlinger.cpp",
"InputTransport.cpp",
"VelocityControl.cpp",
"VelocityTracker.cpp",
"InputApplication.cpp",
- "InputWindow.cpp"
+ "InputWindow.cpp",
+ "IInputFlinger.cpp"
],
shared_libs: [
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
index 003e73d..47a2c0c 100644
--- a/libs/input/IInputFlinger.cpp
+++ b/libs/input/IInputFlinger.cpp
@@ -23,7 +23,6 @@
#include <input/IInputFlinger.h>
-
namespace android {
class BpInputFlinger : public BpInterface<IInputFlinger> {
@@ -31,23 +30,35 @@
explicit BpInputFlinger(const sp<IBinder>& impl) :
BpInterface<IInputFlinger>(impl) { }
- virtual status_t doSomething() {
+ virtual void setInputWindows(const Vector<InputWindowInfo>& inputInfo) {
Parcel data, reply;
data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
- remote()->transact(BnInputFlinger::DO_SOMETHING_TRANSACTION, data, &reply);
- return reply.readInt32();
+
+ data.writeUint32(static_cast<uint32_t>(inputInfo.size()));
+ for (const auto& info : inputInfo) {
+ info.write(data);
+ }
+ remote()->transact(BnInputFlinger::SET_INPUT_WINDOWS_TRANSACTION, data, &reply);
}
};
IMPLEMENT_META_INTERFACE(InputFlinger, "android.input.IInputFlinger");
-
status_t BnInputFlinger::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
switch(code) {
- case DO_SOMETHING_TRANSACTION: {
+ case SET_INPUT_WINDOWS_TRANSACTION: {
CHECK_INTERFACE(IInputFlinger, data, reply);
- reply->writeInt32(0);
+ size_t count = data.readUint32();
+ if (count > data.dataSize()) {
+ return BAD_VALUE;
+ }
+ Vector<InputWindowInfo> handles;
+ handles.setCapacity(count);
+ for (size_t i = 0; i < count; i++) {
+ handles.add(InputWindowInfo(data));
+ }
+ setInputWindows(handles);
break;
}
default:
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 32444f9..e93f3a4 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -247,6 +247,10 @@
if (s != OK) {
return s;
}
+ s = out.writeStrongBinder(mToken);
+ if (s != OK) {
+ return s;
+ }
s = out.writeDupFileDescriptor(getFd());
@@ -255,6 +259,7 @@
status_t InputChannel::read(const Parcel& from) {
mName = from.readString8();
+ mToken = from.readStrongBinder();
int rawFd = from.readFileDescriptor();
setFd(::dup(rawFd));
@@ -266,6 +271,17 @@
return OK;
}
+sp<IBinder> InputChannel::getToken() 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/InputWindow.cpp b/libs/input/InputWindow.cpp
index 6968661..f82437e 100644
--- a/libs/input/InputWindow.cpp
+++ b/libs/input/InputWindow.cpp
@@ -135,6 +135,10 @@
return ret;
}
+InputWindowInfo::InputWindowInfo(const Parcel& from) {
+ *this = read(from);
+}
+
// --- InputWindowHandle ---
InputWindowHandle::InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle) :
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 9a65452..7812cb2 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -35,6 +35,7 @@
"libutils",
"libui",
"libhardware_legacy",
+ "libutils"
],
cflags: [
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 177f832..0c9e04b 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -58,6 +58,7 @@
#include <utils/Trace.h>
#include <powermanager/PowerManager.h>
#include <ui/Region.h>
+#include <binder/Binder.h>
#define INDENT " "
#define INDENT2 " "
@@ -818,7 +819,7 @@
sp<InputWindowHandle> focusedWindowHandle =
getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
if (focusedWindowHandle != nullptr) {
- commandEntry->inputWindowHandle = focusedWindowHandle;
+ commandEntry->inputChannel = focusedWindowHandle->getInputChannel();
}
commandEntry->keyEntry = entry;
entry->refCount += 1;
@@ -1064,6 +1065,13 @@
}
}
+void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
+ for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
+ TouchState& state = mTouchStatesByDisplay.editValueAt(d);
+ state.removeWindowByToken(token);
+ }
+}
+
void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
const sp<InputChannel>& inputChannel) {
if (newTimeout > 0) {
@@ -1078,17 +1086,10 @@
ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
if (connectionIndex >= 0) {
sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
- sp<InputWindowHandle> windowHandle = connection->inputWindowHandle;
+ sp<IBinder> token = connection->inputChannel->getToken();
- if (windowHandle != nullptr) {
- const InputWindowInfo* info = windowHandle->getInfo();
- if (info) {
- ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(info->displayId);
- if (stateIndex >= 0) {
- mTouchStatesByDisplay.editValueAt(stateIndex).removeWindow(
- windowHandle);
- }
- }
+ if (token != nullptr) {
+ removeWindowByTokenLocked(token);
}
if (connection->status == Connection::STATUS_NORMAL) {
@@ -3017,7 +3018,8 @@
const Vector<sp<InputWindowHandle>> windowHandles = it.second;
size_t numWindows = windowHandles.size();
for (size_t i = 0; i < numWindows; i++) {
- if (windowHandles.itemAt(i) == windowHandle) {
+ if (windowHandles.itemAt(i)->getInputChannel()->getToken()
+ == windowHandle->getInputChannel()->getToken()) {
if (windowHandle->getInfo()->displayId != it.first) {
ALOGE("Found window %s in display %" PRId32
", but it should belong to display %" PRId32,
@@ -3639,8 +3641,7 @@
mConfig.keyRepeatTimeout * 0.000001f);
}
-status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, int32_t displayId) {
+status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, int32_t displayId) {
#if DEBUG_REGISTRATION
ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
inputChannel->getName().c_str(), displayId);
@@ -3649,17 +3650,20 @@
{ // acquire lock
AutoMutex _l(mLock);
+ // If InputWindowHandle is null and displayId is not ADISPLAY_ID_NONE,
+ // treat inputChannel as monitor channel for displayId.
+ bool monitor = inputChannel->getToken() == nullptr && displayId != ADISPLAY_ID_NONE;
+ if (monitor) {
+ inputChannel->setToken(new BBinder());
+ }
+
if (getConnectionIndexLocked(inputChannel) >= 0) {
ALOGW("Attempted to register already registered input channel '%s'",
inputChannel->getName().c_str());
return BAD_VALUE;
}
- // If InputWindowHandle is null and displayId is not ADISPLAY_ID_NONE,
- // treat inputChannel as monitor channel for displayId.
- bool monitor = inputWindowHandle == nullptr && displayId != ADISPLAY_ID_NONE;
-
- sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
+ sp<Connection> connection = new Connection(inputChannel, monitor);
int fd = inputChannel->getFd();
mConnectionsByFd.add(fd, connection);
@@ -3744,17 +3748,17 @@
}
ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
- if (!inputChannel) {
+ if (inputChannel == nullptr) {
return -1;
}
- ssize_t connectionIndex = mConnectionsByFd.indexOfKey(inputChannel->getFd());
- if (connectionIndex >= 0) {
- sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
- if (connection->inputChannel.get() == inputChannel.get()) {
- return connectionIndex;
+ for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
+ sp<Connection> connection = mConnectionsByFd.valueAt(i);
+ if (connection->inputChannel->getToken() == inputChannel->getToken()) {
+ return i;
}
}
+
return -1;
}
@@ -3808,7 +3812,7 @@
CommandEntry* commandEntry = postCommandLocked(
& InputDispatcher::doNotifyANRLockedInterruptible);
commandEntry->inputApplicationHandle = applicationHandle;
- commandEntry->inputWindowHandle = windowHandle;
+ commandEntry->inputChannel = windowHandle != nullptr ? windowHandle->getInputChannel() : nullptr;
commandEntry->reason = reason;
}
@@ -3828,7 +3832,7 @@
if (connection->status != Connection::STATUS_ZOMBIE) {
mLock.unlock();
- mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
+ mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
mLock.lock();
}
@@ -3839,14 +3843,14 @@
mLock.unlock();
nsecs_t newTimeout = mPolicy->notifyANR(
- commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle,
+ commandEntry->inputApplicationHandle,
+ commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr,
commandEntry->reason);
mLock.lock();
resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
- commandEntry->inputWindowHandle != nullptr
- ? commandEntry->inputWindowHandle->getInputChannel() : nullptr);
+ commandEntry->inputChannel);
}
void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
@@ -3859,7 +3863,9 @@
mLock.unlock();
android::base::Timer t;
- nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
+ sp<IBinder> token = commandEntry->inputChannel != nullptr ?
+ commandEntry->inputChannel->getToken() : nullptr;
+ nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token,
&event, entry->policyFlags);
if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
@@ -3960,7 +3966,7 @@
mLock.unlock();
- mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
+ mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
&event, keyEntry->policyFlags, &event);
mLock.lock();
@@ -4005,7 +4011,7 @@
mLock.unlock();
- bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
+ bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
&event, keyEntry->policyFlags, &event);
mLock.lock();
@@ -4721,9 +4727,8 @@
// --- InputDispatcher::Connection ---
-InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
- status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
+InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor) :
+ status(STATUS_NORMAL), inputChannel(inputChannel),
monitor(monitor),
inputPublisher(inputChannel), inputPublisherBlocked(false) {
}
@@ -4732,8 +4737,8 @@
}
const std::string InputDispatcher::Connection::getWindowName() const {
- if (inputWindowHandle != nullptr) {
- return inputWindowHandle->getName();
+ if (inputChannel != nullptr) {
+ return inputChannel->getName();
}
if (monitor) {
return "monitor";
@@ -4840,6 +4845,15 @@
}
}
+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) {
+ windows.removeAt(i);
+ return;
+ }
+ }
+}
+
void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
for (size_t i = 0 ; i < windows.size(); ) {
TouchedWindow& window = windows.editItemAt(i);
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 5efb2fa..5016082 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -208,11 +208,11 @@
/* Notifies the system that an application is not responding.
* Returns a new timeout to continue waiting, or 0 to abort dispatch. */
virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
- const sp<InputWindowHandle>& inputWindowHandle,
+ const sp<IBinder>& token,
const std::string& reason) = 0;
/* Notifies the system that an input channel is unrecoverably broken. */
- virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0;
+ virtual void notifyInputChannelBroken(const sp<IBinder>& token) = 0;
/* Gets the input dispatcher configuration. */
virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) = 0;
@@ -243,12 +243,12 @@
virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
/* Allows the policy a chance to intercept a key before dispatching. */
- virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
+ virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token,
const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
/* Allows the policy a chance to perform default processing for an unhandled key.
* Returns an alternate keycode to redispatch as a fallback, or 0 to give up. */
- virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
+ virtual bool dispatchUnhandledKey(const sp<IBinder>& token,
const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) = 0;
/* Notifies the policy about switch events.
@@ -352,8 +352,8 @@
*
* This method may be called on any thread (usually by the input manager).
*/
- virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, int32_t displayId) = 0;
+ virtual status_t registerInputChannel(
+ const sp<InputChannel>& inputChannel, int32_t displayId) = 0;
/* Unregister input channels that will no longer receive input events.
*
@@ -413,7 +413,7 @@
const sp<InputChannel>& toChannel);
virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, int32_t displayId);
+ int32_t displayId);
virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
private:
@@ -617,11 +617,11 @@
nsecs_t eventTime;
KeyEntry* keyEntry;
sp<InputApplicationHandle> inputApplicationHandle;
- sp<InputWindowHandle> inputWindowHandle;
std::string reason;
int32_t userActivityEventType;
uint32_t seq;
bool handled;
+ sp<InputChannel> inputChannel;
};
// Generic queue implementation.
@@ -834,7 +834,6 @@
Status status;
sp<InputChannel> inputChannel; // never null
- sp<InputWindowHandle> inputWindowHandle; // may be null
bool monitor;
InputPublisher inputPublisher;
InputState inputState;
@@ -850,8 +849,7 @@
// yet received a "finished" response from the application.
Queue<DispatchEntry> waitQueue;
- explicit Connection(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
+ explicit Connection(const sp<InputChannel>& inputChannel, bool monitor);
inline const std::string getInputChannelName() const { return inputChannel->getName(); }
@@ -1007,6 +1005,7 @@
void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds);
void removeWindow(const sp<InputWindowHandle>& windowHandle);
+ void removeWindowByToken(const sp<IBinder>& token);
void filterNonAsIsTouchWindows();
sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
bool isSlippery() const;
@@ -1062,6 +1061,9 @@
const sp<InputApplicationHandle>& applicationHandle,
const sp<InputWindowHandle>& windowHandle,
nsecs_t* nextWakeupTime, const char* reason);
+
+ void removeWindowByTokenLocked(const sp<IBinder>& token);
+
void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
const sp<InputChannel>& inputChannel);
nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime);
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 519faa6..40ca6a7 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -21,6 +21,7 @@
#include "InputManager.h"
#include <log/log.h>
+#include <unordered_map>
namespace android {
@@ -90,4 +91,39 @@
return mDispatcher;
}
+class BinderApplicationHandle : public InputApplicationHandle {
+public:
+ BinderApplicationHandle() = default;
+
+ bool updateInfo() override {
+ return true;
+ }
+};
+
+class BinderWindowHandle : public InputWindowHandle {
+public:
+ BinderWindowHandle(const InputWindowInfo& info) :
+ InputWindowHandle(new BinderApplicationHandle()) {
+
+ mInfo = info;
+ }
+
+ bool updateInfo() override {
+ return true;
+ }
+};
+
+void InputManager::setInputWindows(const Vector<InputWindowInfo>& infos) {
+ std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> handlesPerDisplay;
+
+ Vector<sp<InputWindowHandle>> handles;
+ for (const auto& info : infos) {
+ handlesPerDisplay.emplace(info.displayId, Vector<sp<InputWindowHandle>>());
+ handlesPerDisplay[info.displayId].add(new BinderWindowHandle(info));
+ }
+ for (auto const& i : handlesPerDisplay) {
+ mDispatcher->setInputWindows(i.second, i.first);
+ }
+}
+
} // namespace android
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index 92e0af2..d0e4cb0 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -27,6 +27,8 @@
#include <input/Input.h>
#include <input/InputTransport.h>
+
+#include <input/IInputFlinger.h>
#include <utils/Errors.h>
#include <utils/Vector.h>
#include <utils/Timers.h>
@@ -72,7 +74,7 @@
virtual sp<InputDispatcherInterface> getDispatcher() = 0;
};
-class InputManager : public InputManagerInterface {
+class InputManager : public InputManagerInterface, public BnInputFlinger {
protected:
virtual ~InputManager();
@@ -93,6 +95,8 @@
virtual sp<InputReaderInterface> getReader();
virtual sp<InputDispatcherInterface> getDispatcher();
+ virtual void setInputWindows(const Vector<InputWindowInfo>& handles);
+
private:
sp<InputReaderInterface> mReader;
sp<InputReaderThread> mReaderThread;
diff --git a/services/inputflinger/host/Android.bp b/services/inputflinger/host/Android.bp
index 775dbdc..0e48f24 100644
--- a/services/inputflinger/host/Android.bp
+++ b/services/inputflinger/host/Android.bp
@@ -30,6 +30,9 @@
"libutils",
"libhardware",
],
+ static_libs: [
+ "libarect",
+ ],
cflags: [
"-Wall",
@@ -54,7 +57,10 @@
shared_libs: [
"libbinder",
"libinputflingerhost",
- "libutils",
+ "libutils"
+ ],
+ static_libs: [
+ "libarect",
],
init_rc: ["inputflinger.rc"],
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index 39e69e5..15ca7b3 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -39,6 +39,7 @@
InputFlinger() ANDROID_API;
virtual status_t dump(int fd, const Vector<String16>& args);
+ void setInputWindows(const Vector<InputWindowInfo>&) {}
private:
virtual ~InputFlinger();
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index a1cd71c..ea42855 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -15,6 +15,7 @@
],
shared_libs: [
"libbase",
+ "libbinder",
"libcutils",
"liblog",
"libutils",
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 066c143..e860db5 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -16,6 +16,8 @@
#include "../InputDispatcher.h"
+#include <binder/Binder.h>
+
#include <gtest/gtest.h>
#include <linux/input.h>
@@ -53,12 +55,12 @@
}
virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&,
- const sp<InputWindowHandle>&,
+ const sp<IBinder>&,
const std::string&) {
return 0;
}
- virtual void notifyInputChannelBroken(const sp<InputWindowHandle>&) {
+ virtual void notifyInputChannelBroken(const sp<IBinder>&) {
}
virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
@@ -75,12 +77,12 @@
virtual void interceptMotionBeforeQueueing(nsecs_t, uint32_t&) {
}
- virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>&,
+ virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
const KeyEvent*, uint32_t) {
return 0;
}
- virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>&,
+ virtual bool dispatchUnhandledKey(const sp<IBinder>&,
const KeyEvent*, uint32_t, KeyEvent*) {
return false;
}
@@ -336,6 +338,7 @@
const std::string name, int32_t displayId) :
mDispatcher(dispatcher), mName(name), mDisplayId(displayId) {
InputChannel::openInputChannelPair(name, mServerChannel, mClientChannel);
+
mConsumer = new InputConsumer(mClientChannel);
}
@@ -366,7 +369,8 @@
InputWindowHandle(inputApplicationHandle),
FakeInputReceiver(dispatcher, name, displayId),
mFocused(false) {
- mDispatcher->registerInputChannel(mServerChannel, this, displayId);
+ mServerChannel->setToken(new BBinder());
+ mDispatcher->registerInputChannel(mServerChannel, displayId);
}
virtual bool updateInfo() {
@@ -649,7 +653,7 @@
public:
FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
int32_t displayId) : FakeInputReceiver(dispatcher, name, displayId) {
- mDispatcher->registerInputChannel(mServerChannel, nullptr, displayId);
+ mDispatcher->registerInputChannel(mServerChannel, displayId);
}
};