Notify applications when input devices change.
This change allows the InputManager to keep track of what input
devices are registered with the system and when they change.
It needs to do this so that it can properly clear its cache of
input device properties (especially the key map!) when changes
occur.
Added new API so that applications can register listeners for
input device changes.
Fixed a minor bug in EventHub where it didn't handle EPOLLHUP
properly so it would spam the log about unsupposed epoll events
until inotify noticed that the device was gone and removed it.
Change-Id: I937d8c601f7185d4299038bce6a2934fe4fdd2b3
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index eac9a1c..e59af4e 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -127,6 +127,7 @@
class FakeInputReaderPolicy : public InputReaderPolicyInterface {
InputReaderConfiguration mConfig;
KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
+ Vector<InputDeviceInfo> mInputDevices;
protected:
virtual ~FakeInputReaderPolicy() { }
@@ -141,10 +142,6 @@
mConfig.setDisplayInfo(displayId, true /*external*/, width, height, orientation);
}
- virtual nsecs_t getVirtualKeyQuietTime() {
- return 0;
- }
-
void addExcludedDeviceName(const String8& deviceName) {
mConfig.excludedDeviceNames.push(deviceName);
}
@@ -157,6 +154,10 @@
return &mConfig;
}
+ const Vector<InputDeviceInfo>& getInputDevices() const {
+ return mInputDevices;
+ }
+
private:
virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) {
*outConfig = mConfig;
@@ -165,6 +166,10 @@
virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
return mPointerControllers.valueFor(deviceId);
}
+
+ virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) {
+ mInputDevices = inputDevices;
+ }
};
@@ -667,6 +672,7 @@
sp<InputListenerInterface> mListener;
int32_t mGlobalMetaState;
bool mUpdateGlobalMetaStateWasCalled;
+ int32_t mGeneration;
public:
FakeInputReaderContext(const sp<EventHubInterface>& eventHub,
@@ -722,6 +728,10 @@
virtual void requestTimeoutAtTime(nsecs_t when) {
}
+
+ virtual int32_t bumpGeneration() {
+ return ++mGeneration;
+ }
};
@@ -887,7 +897,8 @@
InputDevice* newDevice(int32_t deviceId, const String8& name, uint32_t classes) {
InputDeviceIdentifier identifier;
identifier.name = name;
- return new InputDevice(&mContext, deviceId, identifier, classes);
+ int32_t generation = deviceId + 1;
+ return new InputDevice(&mContext, deviceId, generation, identifier, classes);
}
protected:
@@ -1045,52 +1056,30 @@
ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
}
-TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsValid) {
+TEST_F(InputReaderTest, GetInputDevices) {
ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
INPUT_DEVICE_CLASS_KEYBOARD, NULL));
+ ASSERT_NO_FATAL_FAILURE(addDevice(2, String8("ignored"),
+ 0, NULL)); // no classes so device will be ignored
- InputDeviceInfo info;
- status_t result = mReader->getInputDeviceInfo(1, &info);
+ Vector<InputDeviceInfo> inputDevices;
+ mReader->getInputDevices(inputDevices);
- ASSERT_EQ(OK, result);
- ASSERT_EQ(1, info.getId());
- ASSERT_STREQ("keyboard", info.getName().string());
- ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, info.getKeyboardType());
- ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, info.getSources());
- ASSERT_EQ(size_t(0), info.getMotionRanges().size());
-}
+ ASSERT_EQ(1U, inputDevices.size());
+ ASSERT_EQ(1, inputDevices[0].getId());
+ ASSERT_STREQ("keyboard", inputDevices[0].getName().string());
+ ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
+ ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
-TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsInvalid) {
- InputDeviceInfo info;
- status_t result = mReader->getInputDeviceInfo(-1, &info);
-
- ASSERT_EQ(NAME_NOT_FOUND, result);
-}
-
-TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsIgnored) {
- addDevice(1, String8("ignored"), 0, NULL); // no classes so device will be ignored
-
- InputDeviceInfo info;
- status_t result = mReader->getInputDeviceInfo(1, &info);
-
- ASSERT_EQ(NAME_NOT_FOUND, result);
-}
-
-TEST_F(InputReaderTest, GetInputDeviceIds) {
- sp<FakePointerController> controller = new FakePointerController();
- mFakePolicy->setPointerController(2, controller);
-
- ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
- INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_ALPHAKEY, NULL));
- ASSERT_NO_FATAL_FAILURE(addDevice(2, String8("mouse"),
- INPUT_DEVICE_CLASS_CURSOR, NULL));
-
- Vector<int32_t> ids;
- mReader->getInputDeviceIds(ids);
-
- ASSERT_EQ(size_t(2), ids.size());
- ASSERT_EQ(1, ids[0]);
- ASSERT_EQ(2, ids[1]);
+ // Should also have received a notification describing the new input devices.
+ inputDevices = mFakePolicy->getInputDevices();
+ ASSERT_EQ(1U, inputDevices.size());
+ ASSERT_EQ(1, inputDevices[0].getId());
+ ASSERT_STREQ("keyboard", inputDevices[0].getName().string());
+ ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
+ ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
}
TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
@@ -1243,6 +1232,7 @@
protected:
static const char* DEVICE_NAME;
static const int32_t DEVICE_ID;
+ static const int32_t DEVICE_GENERATION;
static const uint32_t DEVICE_CLASSES;
sp<FakeEventHub> mFakeEventHub;
@@ -1261,7 +1251,8 @@
mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
InputDeviceIdentifier identifier;
identifier.name = DEVICE_NAME;
- mDevice = new InputDevice(mFakeContext, DEVICE_ID, identifier, DEVICE_CLASSES);
+ mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
+ identifier, DEVICE_CLASSES);
}
virtual void TearDown() {
@@ -1276,6 +1267,7 @@
const char* InputDeviceTest::DEVICE_NAME = "device";
const int32_t InputDeviceTest::DEVICE_ID = 1;
+const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
const uint32_t InputDeviceTest::DEVICE_CLASSES = INPUT_DEVICE_CLASS_KEYBOARD
| INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_JOYSTICK;
@@ -1428,6 +1420,7 @@
protected:
static const char* DEVICE_NAME;
static const int32_t DEVICE_ID;
+ static const int32_t DEVICE_GENERATION;
static const uint32_t DEVICE_CLASSES;
sp<FakeEventHub> mFakeEventHub;
@@ -1443,7 +1436,8 @@
mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
InputDeviceIdentifier identifier;
identifier.name = DEVICE_NAME;
- mDevice = new InputDevice(mFakeContext, DEVICE_ID, identifier, DEVICE_CLASSES);
+ mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
+ identifier, DEVICE_CLASSES);
mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
}
@@ -1522,6 +1516,7 @@
const char* InputMapperTest::DEVICE_NAME = "device";
const int32_t InputMapperTest::DEVICE_ID = 1;
+const int32_t InputMapperTest::DEVICE_GENERATION = 2;
const uint32_t InputMapperTest::DEVICE_CLASSES = 0; // not needed for current tests