Support multiple EventHub devices per InputDevice
Some physical devices contain more functions than can be addressed by
a single Linux evdev device. Examples of such devices are the Sony
DualShock 4 and Wacom Tablets, which appear as multiple evdev devices
sharing the same value for the EVIOCGUNIQ ioctl. As more instances of
such devices hit the market, apps need a way of figuring out which
InputDevices are part of the same physical device.
Per conversation with the android input team, a solution proposed to
this problem is to merge multiple EventHub devices (which have a 1:1
relation with evdev) into a single android InputDevice.
Changes:
Decouple the EventHub device id ("eventHubId") from the InputDevice
device id ("deviceId"). This requires InputDeviceContext to track the
the EventHub devices it represents. Most logic changes are inside
InputDeviceContext, so there are minimal changes to InputMappers.
Added enum value END_RESERVED_ID to represent the first available
id that can be assigned to a normal InputDevice. The android
framework assumes specific values for the virtual keyboard and
built-in hardware keyboard, so for these two cases, the "deviceId"
must match the "eventHubId."
Added "EVENTHUB_ID" constants to tests and changed where applicable.
Cherry-picked from pa/1475694.
Bug: 38511270
Test: atest inputflinger_tests libinput_tests
Change-Id: I89df085fadc1c09bc999599ac5db35c9277c4a2a
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h
index b6efc82..20a17e3 100644
--- a/include/input/InputDevice.h
+++ b/include/input/InputDevice.h
@@ -180,6 +180,8 @@
VIRTUAL_KEYBOARD_ID = -1,
// Device id of the "built-in" keyboard if there is one.
BUILT_IN_KEYBOARD_ID = 0,
+ // First device id available for dynamic devices
+ END_RESERVED_ID = 1,
};
} // namespace android
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index ae82cd4..d0eee64 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -18,6 +18,8 @@
#include "InputDevice.h"
+#include <algorithm>
+
#include "CursorInputMapper.h"
#include "ExternalStylusInputMapper.h"
#include "InputReaderContext.h"
@@ -32,25 +34,28 @@
namespace android {
InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
- int32_t controllerNumber, const InputDeviceIdentifier& identifier,
- uint32_t classes)
+ const InputDeviceIdentifier& identifier)
: mContext(context),
mId(id),
mGeneration(generation),
- mControllerNumber(controllerNumber),
+ mControllerNumber(0),
mIdentifier(identifier),
- mClasses(classes),
+ mClasses(0),
mSources(0),
mIsExternal(false),
mHasMic(false),
- mDropUntilNextSync(false) {
- mDeviceContext = std::make_unique<InputDeviceContext>(*this);
-}
+ mDropUntilNextSync(false) {}
InputDevice::~InputDevice() {}
bool InputDevice::isEnabled() {
- return mDeviceContext->isDeviceEnabled();
+ if (!hasEventHubDevices()) {
+ return false;
+ }
+ // devices are either all enabled or all disabled, so we only need to check the first
+ auto& devicePair = mDevices.begin()->second;
+ auto& contextPtr = devicePair.first;
+ return contextPtr->isDeviceEnabled();
}
void InputDevice::setEnabled(bool enabled, nsecs_t when) {
@@ -65,12 +70,15 @@
return;
}
+ // When resetting some devices, the driver needs to be queried to ensure that a proper reset is
+ // performed. The querying must happen when the device is enabled, so we reset after enabling
+ // but before disabling the device. See MultiTouchMotionAccumulator::reset for more information.
if (enabled) {
- mDeviceContext->enableDevice();
+ for_each_subdevice([](auto& context) { context.enableDevice(); });
reset(when);
} else {
reset(when);
- mDeviceContext->disableDevice();
+ for_each_subdevice([](auto& context) { context.disableDevice(); });
}
// Must change generation to flag this device as changed
bumpGeneration();
@@ -118,19 +126,18 @@
for_each_mapper([&dump](InputMapper& mapper) { mapper.dump(dump); });
}
-void InputDevice::populateMappers() {
- uint32_t classes = mClasses;
- std::vector<std::unique_ptr<InputMapper>>& mappers = mMappers;
- std::unique_ptr<InputDeviceContext>& contextPtr = mDeviceContext;
-
- // External devices.
- if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
- setExternal(true);
+void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
+ if (mDevices.find(eventHubId) != mDevices.end()) {
+ return;
}
+ std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
+ uint32_t classes = contextPtr->getDeviceClasses();
+ std::vector<std::unique_ptr<InputMapper>> mappers;
- // Devices with mics.
- if (classes & INPUT_DEVICE_CLASS_MIC) {
- setMic(true);
+ // Check if we should skip population
+ if (!populateMappers) {
+ mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
+ return;
}
// Switch-like devices.
@@ -190,22 +197,58 @@
if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
mappers.push_back(std::make_unique<ExternalStylusInputMapper>(*contextPtr));
}
+
+ // insert the context into the devices set
+ mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
+}
+
+void InputDevice::removeEventHubDevice(int32_t eventHubId) {
+ mDevices.erase(eventHubId);
}
void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config,
uint32_t changes) {
mSources = 0;
+ mClasses = 0;
+ mControllerNumber = 0;
+
+ for_each_subdevice([this](InputDeviceContext& context) {
+ mClasses |= context.getDeviceClasses();
+ int32_t controllerNumber = context.getDeviceControllerNumber();
+ if (controllerNumber > 0) {
+ if (mControllerNumber && mControllerNumber != controllerNumber) {
+ ALOGW("InputDevice::configure(): composite device contains multiple unique "
+ "controller numbers");
+ }
+ mControllerNumber = controllerNumber;
+ }
+ });
+
+ mIsExternal = !!(mClasses & INPUT_DEVICE_CLASS_EXTERNAL);
+ mHasMic = !!(mClasses & INPUT_DEVICE_CLASS_MIC);
if (!isIgnored()) {
if (!changes) { // first time only
- mDeviceContext->getConfiguration(&mConfiguration);
+ mConfiguration.clear();
+ for_each_subdevice([this](InputDeviceContext& context) {
+ PropertyMap configuration;
+ context.getConfiguration(&configuration);
+ mConfiguration.addAll(&configuration);
+ });
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
sp<KeyCharacterMap> keyboardLayout =
mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
- if (mDeviceContext->setKeyboardLayoutOverlay(keyboardLayout)) {
+ bool shouldBumpGeneration = false;
+ for_each_subdevice(
+ [&keyboardLayout, &shouldBumpGeneration](InputDeviceContext& context) {
+ if (context.setKeyboardLayoutOverlay(keyboardLayout)) {
+ shouldBumpGeneration = true;
+ }
+ });
+ if (shouldBumpGeneration) {
bumpGeneration();
}
}
@@ -313,7 +356,9 @@
mDropUntilNextSync = true;
reset(rawEvent->when);
} else {
- for_each_mapper([rawEvent](InputMapper& mapper) { mapper.process(rawEvent); });
+ for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
+ mapper.process(rawEvent);
+ });
}
--count;
}
@@ -348,16 +393,20 @@
int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
int32_t result = AKEY_STATE_UNKNOWN;
- for (auto& mapperPtr : mMappers) {
- InputMapper& mapper = *mapperPtr;
- if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
- // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
- // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
- int32_t currentResult = (mapper.*getStateFunc)(sourceMask, code);
- if (currentResult >= AKEY_STATE_DOWN) {
- return currentResult;
- } else if (currentResult == AKEY_STATE_UP) {
- result = currentResult;
+ for (auto& deviceEntry : mDevices) {
+ auto& devicePair = deviceEntry.second;
+ auto& mappers = devicePair.second;
+ for (auto& mapperPtr : mappers) {
+ InputMapper& mapper = *mapperPtr;
+ if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
+ // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
+ // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
+ int32_t currentResult = (mapper.*getStateFunc)(sourceMask, code);
+ if (currentResult >= AKEY_STATE_DOWN) {
+ return currentResult;
+ } else if (currentResult == AKEY_STATE_UP) {
+ result = currentResult;
+ }
}
}
}
@@ -424,11 +473,23 @@
[](InputMapper& mapper) { return mapper.getAssociatedDisplayId(); });
}
-InputDeviceContext::InputDeviceContext(InputDevice& device)
+// returns the number of mappers associated with the device
+size_t InputDevice::getMapperCount() {
+ size_t count = 0;
+ for (auto& deviceEntry : mDevices) {
+ auto& devicePair = deviceEntry.second;
+ auto& mappers = devicePair.second;
+ count += mappers.size();
+ }
+ return count;
+}
+
+InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId)
: mDevice(device),
mContext(device.getContext()),
mEventHub(device.getContext()->getEventHub()),
- mId(device.getId()) {}
+ mId(eventHubId),
+ mDeviceId(device.getId()) {}
InputDeviceContext::~InputDeviceContext() {}
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 8327ed8..cbfa702 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -49,6 +49,7 @@
mNextSequenceNum(1),
mGlobalMetaState(0),
mGeneration(1),
+ mNextInputDeviceId(END_RESERVED_ID),
mDisableVirtualKeysTimeout(LLONG_MIN),
mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
@@ -184,30 +185,28 @@
}
}
-void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
- if (mDevices.find(deviceId) != mDevices.end()) {
- ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
+void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
+ if (mDevices.find(eventHubId) != mDevices.end()) {
+ ALOGW("Ignoring spurious device added event for eventHubId %d.", eventHubId);
return;
}
- InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
- uint32_t classes = mEventHub->getDeviceClasses(deviceId);
- int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
-
- std::shared_ptr<InputDevice> device =
- createDeviceLocked(deviceId, controllerNumber, identifier, classes);
+ InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
+ std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
device->configure(when, &mConfig, 0);
device->reset(when);
if (device->isIgnored()) {
- ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
- identifier.name.c_str());
+ ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
+ "(ignored non-input device)",
+ device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str());
} else {
- ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId, identifier.name.c_str(),
+ ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s',sources=0x%08x",
+ device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str(),
device->getSources());
}
- mDevices.emplace(deviceId, device);
+ mDevices.emplace(eventHubId, device);
bumpGenerationLocked();
if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
@@ -215,10 +214,10 @@
}
}
-void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
- auto deviceIt = mDevices.find(deviceId);
+void InputReader::removeDeviceLocked(nsecs_t when, int32_t eventHubId) {
+ auto deviceIt = mDevices.find(eventHubId);
if (deviceIt == mDevices.end()) {
- ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
+ ALOGW("Ignoring spurious device removed event for eventHubId %d.", eventHubId);
return;
}
@@ -227,35 +226,52 @@
bumpGenerationLocked();
if (device->isIgnored()) {
- ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)", device->getId(),
- device->getName().c_str());
+ ALOGI("Device removed: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
+ "(ignored non-input device)",
+ device->getId(), eventHubId, device->getName().c_str(),
+ device->getDescriptor().c_str());
} else {
- ALOGI("Device removed: id=%d, name='%s', sources=0x%08x", device->getId(),
- device->getName().c_str(), device->getSources());
+ ALOGI("Device removed: id=%d, eventHubId=%d, name='%s', descriptor='%s', sources=0x%08x",
+ device->getId(), eventHubId, device->getName().c_str(),
+ device->getDescriptor().c_str(), device->getSources());
}
+ device->removeEventHubDevice(eventHubId);
+
if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
notifyExternalStylusPresenceChanged();
}
+ if (device->hasEventHubDevices()) {
+ device->configure(when, &mConfig, 0);
+ }
device->reset(when);
}
std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
- int32_t deviceId, int32_t controllerNumber, const InputDeviceIdentifier& identifier,
- uint32_t classes) {
- std::shared_ptr<InputDevice> device =
- std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(),
- controllerNumber, identifier, classes);
- device->populateMappers();
+ int32_t eventHubId, const InputDeviceIdentifier& identifier) {
+ auto deviceIt = std::find_if(mDevices.begin(), mDevices.end(), [identifier](auto& devicePair) {
+ return devicePair.second->getDescriptor().size() && identifier.descriptor.size() &&
+ devicePair.second->getDescriptor() == identifier.descriptor;
+ });
+
+ std::shared_ptr<InputDevice> device;
+ if (deviceIt != mDevices.end()) {
+ device = deviceIt->second;
+ } else {
+ int32_t deviceId = (eventHubId < END_RESERVED_ID) ? eventHubId : nextInputDeviceIdLocked();
+ device = std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(),
+ identifier);
+ }
+ device->addEventHubDevice(eventHubId);
return device;
}
-void InputReader::processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents,
+void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
size_t count) {
- auto deviceIt = mDevices.find(deviceId);
+ auto deviceIt = mDevices.find(eventHubId);
if (deviceIt == mDevices.end()) {
- ALOGW("Discarding event for unknown deviceId %d.", deviceId);
+ ALOGW("Discarding event for unknown eventHubId %d.", eventHubId);
return;
}
@@ -268,6 +284,17 @@
device->process(rawEvents, count);
}
+InputDevice* InputReader::findInputDevice(int32_t deviceId) {
+ auto deviceIt =
+ std::find_if(mDevices.begin(), mDevices.end(), [deviceId](const auto& devicePair) {
+ return devicePair.second->getId() == deviceId;
+ });
+ if (deviceIt != mDevices.end()) {
+ return deviceIt->second.get();
+ }
+ return nullptr;
+}
+
void InputReader::timeoutExpiredLocked(nsecs_t when) {
for (auto& devicePair : mDevices) {
std::shared_ptr<InputDevice>& device = devicePair.second;
@@ -277,6 +304,10 @@
}
}
+int32_t InputReader::nextInputDeviceIdLocked() {
+ return ++mNextInputDeviceId;
+}
+
void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
// Reset global meta state because it depends on the list of all configured devices.
updateGlobalMetaStateLocked();
@@ -414,12 +445,9 @@
GetStateFunc getStateFunc) {
int32_t result = AKEY_STATE_UNKNOWN;
if (deviceId >= 0) {
- auto deviceIt = mDevices.find(deviceId);
- if (deviceIt != mDevices.end()) {
- std::shared_ptr<InputDevice>& device = deviceIt->second;
- if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = (device.get()->*getStateFunc)(sourceMask, code);
- }
+ InputDevice* device = findInputDevice(deviceId);
+ if (device && !device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = (device->*getStateFunc)(sourceMask, code);
}
} else {
for (auto& devicePair : mDevices) {
@@ -440,13 +468,12 @@
}
void InputReader::toggleCapsLockState(int32_t deviceId) {
- auto deviceIt = mDevices.find(deviceId);
- if (deviceIt == mDevices.end()) {
+ InputDevice* device = findInputDevice(deviceId);
+ if (!device) {
ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
return;
}
- std::shared_ptr<InputDevice>& device = deviceIt->second;
if (device->isIgnored()) {
return;
}
@@ -467,12 +494,9 @@
uint8_t* outFlags) {
bool result = false;
if (deviceId >= 0) {
- auto deviceIt = mDevices.find(deviceId);
- if (deviceIt != mDevices.end()) {
- std::shared_ptr<InputDevice>& device = deviceIt->second;
- if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
- }
+ InputDevice* device = findInputDevice(deviceId);
+ if (device && !device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
}
} else {
for (auto& devicePair : mDevices) {
@@ -501,9 +525,8 @@
void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
ssize_t repeat, int32_t token) {
AutoMutex _l(mLock);
- auto deviceIt = mDevices.find(deviceId);
- if (deviceIt != mDevices.end()) {
- std::shared_ptr<InputDevice>& device = deviceIt->second;
+ InputDevice* device = findInputDevice(deviceId);
+ if (device) {
device->vibrate(pattern, patternSize, repeat, token);
}
}
@@ -511,9 +534,8 @@
void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
AutoMutex _l(mLock);
- auto deviceIt = mDevices.find(deviceId);
- if (deviceIt != mDevices.end()) {
- std::shared_ptr<InputDevice>& device = deviceIt->second;
+ InputDevice* device = findInputDevice(deviceId);
+ if (device) {
device->cancelVibrate(token);
}
}
@@ -521,9 +543,8 @@
bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
AutoMutex _l(mLock);
- auto deviceIt = mDevices.find(deviceId);
- if (deviceIt != mDevices.end()) {
- std::shared_ptr<InputDevice>& device = deviceIt->second;
+ InputDevice* device = findInputDevice(deviceId);
+ if (device) {
return device->isEnabled();
}
ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
@@ -533,13 +554,12 @@
bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
AutoMutex _l(mLock);
- auto deviceIt = mDevices.find(deviceId);
- if (deviceIt == mDevices.end()) {
+ InputDevice* device = findInputDevice(deviceId);
+ if (!device) {
ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
return false;
}
- std::shared_ptr<InputDevice>& device = deviceIt->second;
if (!device->isEnabled()) {
ALOGW("Ignoring disabled device %s", device->getName().c_str());
return false;
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index 0814d1f..aaa0d26 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -17,18 +17,19 @@
#ifndef _UI_INPUTREADER_INPUT_DEVICE_H
#define _UI_INPUTREADER_INPUT_DEVICE_H
+#include <input/DisplayViewport.h>
+#include <input/InputDevice.h>
+#include <stdint.h>
+#include <utils/PropertyMap.h>
+
+#include <optional>
+#include <unordered_map>
+#include <vector>
+
#include "EventHub.h"
#include "InputReaderBase.h"
#include "InputReaderContext.h"
-#include <input/DisplayViewport.h>
-#include <input/InputDevice.h>
-#include <utils/PropertyMap.h>
-
-#include <stdint.h>
-#include <optional>
-#include <vector>
-
namespace android {
class InputDeviceContext;
@@ -38,8 +39,7 @@
class InputDevice {
public:
InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
- int32_t controllerNumber, const InputDeviceIdentifier& identifier,
- uint32_t classes);
+ const InputDeviceIdentifier& identifier);
~InputDevice();
inline InputReaderContext* getContext() { return mContext; }
@@ -50,25 +50,25 @@
inline const std::string getDescriptor() { return mIdentifier.descriptor; }
inline uint32_t getClasses() const { return mClasses; }
inline uint32_t getSources() const { return mSources; }
+ inline bool hasEventHubDevices() const { return !mDevices.empty(); }
inline bool isExternal() { return mIsExternal; }
- inline void setExternal(bool external) { mIsExternal = external; }
inline std::optional<uint8_t> getAssociatedDisplayPort() const {
return mAssociatedDisplayPort;
}
inline std::optional<DisplayViewport> getAssociatedViewport() const {
return mAssociatedViewport;
}
- inline void setMic(bool hasMic) { mHasMic = hasMic; }
inline bool hasMic() const { return mHasMic; }
- inline bool isIgnored() { return mMappers.empty(); }
+ inline bool isIgnored() { return !getMapperCount(); }
bool isEnabled();
void setEnabled(bool enabled, nsecs_t when);
void dump(std::string& dump);
- void populateMappers();
+ void addEventHubDevice(int32_t eventHubId, bool populateMappers = true);
+ void removeEventHubDevice(int32_t eventHubId);
void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
void reset(nsecs_t when);
void process(const RawEvent* rawEvents, size_t count);
@@ -99,11 +99,20 @@
std::optional<int32_t> getAssociatedDisplayId();
+ size_t getMapperCount();
+
// construct and add a mapper to the input device
template <class T, typename... Args>
- T& addMapper(Args... args) {
- T* mapper = new T(*mDeviceContext, args...);
- mMappers.emplace_back(mapper);
+ T& addMapper(int32_t eventHubId, Args... args) {
+ // ensure a device entry exists for this eventHubId
+ addEventHubDevice(eventHubId, false);
+
+ // create mapper
+ auto& devicePair = mDevices[eventHubId];
+ auto& deviceContext = devicePair.first;
+ auto& mappers = devicePair.second;
+ T* mapper = new T(*deviceContext, args...);
+ mappers.emplace_back(mapper);
return *mapper;
}
@@ -116,8 +125,10 @@
std::string mAlias;
uint32_t mClasses;
- std::unique_ptr<InputDeviceContext> mDeviceContext;
- std::vector<std::unique_ptr<InputMapper>> mMappers;
+ // map from eventHubId to device context and mappers
+ using MapperVector = std::vector<std::unique_ptr<InputMapper>>;
+ using DevicePair = std::pair<std::unique_ptr<InputDeviceContext>, MapperVector>;
+ std::unordered_map<int32_t, DevicePair> mDevices;
uint32_t mSources;
bool mIsExternal;
@@ -131,10 +142,37 @@
PropertyMap mConfiguration;
- // run a function against every mapper
+ // helpers to interate over the devices collection
+ // run a function against every mapper on every subdevice
inline void for_each_mapper(std::function<void(InputMapper&)> f) {
- for (auto& mapperPtr : mMappers) {
- f(*mapperPtr);
+ for (auto& deviceEntry : mDevices) {
+ auto& devicePair = deviceEntry.second;
+ auto& mappers = devicePair.second;
+ for (auto& mapperPtr : mappers) {
+ f(*mapperPtr);
+ }
+ }
+ }
+
+ // run a function against every mapper on a specific subdevice
+ inline void for_each_mapper_in_subdevice(int32_t eventHubDevice,
+ std::function<void(InputMapper&)> f) {
+ auto deviceIt = mDevices.find(eventHubDevice);
+ if (deviceIt != mDevices.end()) {
+ auto& devicePair = deviceIt->second;
+ auto& mappers = devicePair.second;
+ for (auto& mapperPtr : mappers) {
+ f(*mapperPtr);
+ }
+ }
+ }
+
+ // run a function against every subdevice
+ inline void for_each_subdevice(std::function<void(InputDeviceContext&)> f) {
+ for (auto& deviceEntry : mDevices) {
+ auto& devicePair = deviceEntry.second;
+ auto& contextPtr = devicePair.first;
+ f(*contextPtr);
}
}
@@ -142,10 +180,14 @@
// if all mappers return nullopt, return nullopt.
template <typename T>
inline std::optional<T> first_in_mappers(std::function<std::optional<T>(InputMapper&)> f) {
- for (auto& mapperPtr : mMappers) {
- std::optional<T> ret = f(*mapperPtr);
- if (ret) {
- return ret;
+ for (auto& deviceEntry : mDevices) {
+ auto& devicePair = deviceEntry.second;
+ auto& mappers = devicePair.second;
+ for (auto& mapperPtr : mappers) {
+ std::optional<T> ret = f(*mapperPtr);
+ if (ret) {
+ return ret;
+ }
}
}
return std::nullopt;
@@ -159,11 +201,12 @@
*/
class InputDeviceContext {
public:
- InputDeviceContext(InputDevice& device);
+ InputDeviceContext(InputDevice& device, int32_t eventHubId);
~InputDeviceContext();
inline InputReaderContext* getContext() { return mContext; }
- inline int32_t getId() { return mId; }
+ inline int32_t getId() { return mDeviceId; }
+ inline int32_t getEventHubId() { return mId; }
inline uint32_t getDeviceClasses() const { return mEventHub->getDeviceClasses(mId); }
inline InputDeviceIdentifier getDeviceIdentifier() const {
@@ -259,6 +302,7 @@
InputReaderContext* mContext;
EventHubInterface* mEventHub;
int32_t mId;
+ int32_t mDeviceId;
};
} // namespace android
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index 4f5d2ea..31d82f1 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -84,10 +84,8 @@
protected:
// These members are protected so they can be instrumented by test cases.
- virtual std::shared_ptr<InputDevice> createDeviceLocked(int32_t deviceId,
- int32_t controllerNumber,
- const InputDeviceIdentifier& identifier,
- uint32_t classes);
+ virtual std::shared_ptr<InputDevice> createDeviceLocked(
+ int32_t deviceId, const InputDeviceIdentifier& identifier);
// With each iteration of the loop, InputReader reads and processes one incoming message from
// the EventHub.
@@ -139,14 +137,16 @@
static const int EVENT_BUFFER_SIZE = 256;
RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
- std::unordered_map<int32_t /*deviceId*/, std::shared_ptr<InputDevice>> mDevices;
+ // An input device can represent a collection of EventHub devices. This map provides a way
+ // to lookup the input device instance from the EventHub device id.
+ std::unordered_map<int32_t /*eventHubId*/, std::shared_ptr<InputDevice>> mDevices;
// low-level input event decoding and device management
void processEventsLocked(const RawEvent* rawEvents, size_t count);
- void addDeviceLocked(nsecs_t when, int32_t deviceId);
- void removeDeviceLocked(nsecs_t when, int32_t deviceId);
- void processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents, size_t count);
+ void addDeviceLocked(nsecs_t when, int32_t eventHubId);
+ void removeDeviceLocked(nsecs_t when, int32_t eventHubId);
+ void processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents, size_t count);
void timeoutExpiredLocked(nsecs_t when);
void handleConfigurationChangedLocked(nsecs_t when);
@@ -164,6 +164,9 @@
int32_t mGeneration;
int32_t bumpGenerationLocked();
+ int32_t mNextInputDeviceId;
+ int32_t nextInputDeviceIdLocked();
+
void getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices);
nsecs_t mDisableVirtualKeysTimeout;
@@ -182,6 +185,9 @@
GetStateFunc getStateFunc);
bool markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags);
+
+ // find an InputDevice from an InputDevice id
+ InputDevice* findInputDevice(int32_t deviceId);
};
} // namespace android
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index d870a01..578605f 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1103,31 +1103,27 @@
void setNextDevice(std::shared_ptr<InputDevice> device) { mNextDevice = device; }
- std::shared_ptr<InputDevice> newDevice(int32_t deviceId, int32_t controllerNumber,
- const std::string& name, uint32_t classes,
+ std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
const std::string& location = "") {
InputDeviceIdentifier identifier;
identifier.name = name;
identifier.location = location;
int32_t generation = deviceId + 1;
- return std::make_shared<InputDevice>(&mContext, deviceId, generation, controllerNumber,
- identifier, classes);
+ return std::make_shared<InputDevice>(&mContext, deviceId, generation, identifier);
}
// Make the protected loopOnce method accessible to tests.
using InputReader::loopOnce;
protected:
- virtual std::shared_ptr<InputDevice> createDeviceLocked(int32_t deviceId,
- int32_t controllerNumber,
- const InputDeviceIdentifier& identifier,
- uint32_t classes) {
+ virtual std::shared_ptr<InputDevice> createDeviceLocked(
+ int32_t eventHubId, const InputDeviceIdentifier& identifier) {
if (mNextDevice) {
std::shared_ptr<InputDevice> device(mNextDevice);
mNextDevice = nullptr;
return device;
}
- return InputReader::createDeviceLocked(deviceId, controllerNumber, identifier, classes);
+ return InputReader::createDeviceLocked(eventHubId, identifier);
}
friend class InputReaderTest;
@@ -1338,12 +1334,12 @@
mFakePolicy.clear();
}
- void addDevice(int32_t deviceId, const std::string& name, uint32_t classes,
- const PropertyMap* configuration) {
- mFakeEventHub->addDevice(deviceId, name, classes);
+ void addDevice(int32_t eventHubId, const std::string& name, uint32_t classes,
+ const PropertyMap* configuration) {
+ mFakeEventHub->addDevice(eventHubId, name, classes);
if (configuration) {
- mFakeEventHub->addConfigurationMap(deviceId, configuration);
+ mFakeEventHub->addConfigurationMap(eventHubId, configuration);
}
mFakeEventHub->finishDeviceScan();
mReader->loopOnce();
@@ -1362,15 +1358,14 @@
mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE);
}
- FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t controllerNumber,
+ FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t eventHubId,
const std::string& name, uint32_t classes,
uint32_t sources,
const PropertyMap* configuration) {
- std::shared_ptr<InputDevice> device =
- mReader->newDevice(deviceId, controllerNumber, name, classes);
- FakeInputMapper& mapper = device->addMapper<FakeInputMapper>(sources);
+ std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, name);
+ FakeInputMapper& mapper = device->addMapper<FakeInputMapper>(eventHubId, sources);
mReader->setNextDevice(device);
- addDevice(deviceId, name, classes, configuration);
+ addDevice(eventHubId, name, classes, configuration);
return mapper;
}
};
@@ -1384,7 +1379,7 @@
std::vector<InputDeviceInfo> inputDevices;
mReader->getInputDevices(inputDevices);
ASSERT_EQ(1U, inputDevices.size());
- ASSERT_EQ(1, inputDevices[0].getId());
+ ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
@@ -1393,7 +1388,7 @@
// 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_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
@@ -1401,14 +1396,14 @@
}
TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
- constexpr int32_t deviceId = 1;
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
- std::shared_ptr<InputDevice> device =
- mReader->newDevice(deviceId, 0 /*controllerNumber*/, "fake", deviceClass);
+ constexpr int32_t eventHubId = 1;
+ std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
// Must add at least one mapper or the device will be ignored!
- device->addMapper<FakeInputMapper>(AINPUT_SOURCE_KEYBOARD);
+ device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
mReader->setNextDevice(device);
- ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
+ ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
@@ -1438,8 +1433,11 @@
}
TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
+ constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
+ constexpr int32_t eventHubId = 1;
FakeInputMapper& mapper =
- addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD,
+ addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
AINPUT_SOURCE_KEYBOARD, nullptr);
mapper.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
@@ -1447,13 +1445,16 @@
AINPUT_SOURCE_ANY, AKEYCODE_A))
<< "Should return unknown when the device id is >= 0 but unknown.";
- ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(1,
- AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
- << "Should return unknown when the device id is valid but the sources are not supported by the device.";
+ ASSERT_EQ(AKEY_STATE_UNKNOWN,
+ mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
+ << "Should return unknown when the device id is valid but the sources are not "
+ "supported by the device.";
- ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(1,
- AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
- << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
+ ASSERT_EQ(AKEY_STATE_DOWN,
+ mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
+ AKEYCODE_A))
+ << "Should return value provided by mapper when device id is valid and the device "
+ "supports some of the sources.";
ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
@@ -1465,8 +1466,11 @@
}
TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
+ constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
+ constexpr int32_t eventHubId = 1;
FakeInputMapper& mapper =
- addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD,
+ addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
AINPUT_SOURCE_KEYBOARD, nullptr);
mapper.setScanCodeState(KEY_A, AKEY_STATE_DOWN);
@@ -1474,13 +1478,16 @@
AINPUT_SOURCE_ANY, KEY_A))
<< "Should return unknown when the device id is >= 0 but unknown.";
- ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(1,
- AINPUT_SOURCE_TRACKBALL, KEY_A))
- << "Should return unknown when the device id is valid but the sources are not supported by the device.";
+ ASSERT_EQ(AKEY_STATE_UNKNOWN,
+ mReader->getScanCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, KEY_A))
+ << "Should return unknown when the device id is valid but the sources are not "
+ "supported by the device.";
- ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(1,
- AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
- << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
+ ASSERT_EQ(AKEY_STATE_DOWN,
+ mReader->getScanCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
+ KEY_A))
+ << "Should return value provided by mapper when device id is valid and the device "
+ "supports some of the sources.";
ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
AINPUT_SOURCE_TRACKBALL, KEY_A))
@@ -1492,8 +1499,11 @@
}
TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
+ constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
+ constexpr int32_t eventHubId = 1;
FakeInputMapper& mapper =
- addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD,
+ addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
AINPUT_SOURCE_KEYBOARD, nullptr);
mapper.setSwitchState(SW_LID, AKEY_STATE_DOWN);
@@ -1501,13 +1511,16 @@
AINPUT_SOURCE_ANY, SW_LID))
<< "Should return unknown when the device id is >= 0 but unknown.";
- ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(1,
- AINPUT_SOURCE_TRACKBALL, SW_LID))
- << "Should return unknown when the device id is valid but the sources are not supported by the device.";
+ ASSERT_EQ(AKEY_STATE_UNKNOWN,
+ mReader->getSwitchState(deviceId, AINPUT_SOURCE_TRACKBALL, SW_LID))
+ << "Should return unknown when the device id is valid but the sources are not "
+ "supported by the device.";
- ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(1,
- AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
- << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
+ ASSERT_EQ(AKEY_STATE_DOWN,
+ mReader->getSwitchState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
+ SW_LID))
+ << "Should return value provided by mapper when device id is valid and the device "
+ "supports some of the sources.";
ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
AINPUT_SOURCE_TRACKBALL, SW_LID))
@@ -1519,8 +1532,11 @@
}
TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
+ constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
+ constexpr int32_t eventHubId = 1;
FakeInputMapper& mapper =
- addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD,
+ addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
AINPUT_SOURCE_KEYBOARD, nullptr);
mapper.addSupportedKeyCode(AKEYCODE_A);
@@ -1534,13 +1550,16 @@
ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
flags[3] = 1;
- ASSERT_FALSE(mReader->hasKeys(1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
- << "Should return false when device id is valid but the sources are not supported by the device.";
+ ASSERT_FALSE(mReader->hasKeys(deviceId, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
+ << "Should return false when device id is valid but the sources are not supported by "
+ "the device.";
ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
flags[3] = 1;
- ASSERT_TRUE(mReader->hasKeys(1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
- << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
+ ASSERT_TRUE(mReader->hasKeys(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4,
+ keyCodes, flags))
+ << "Should return value provided by mapper when device id is valid and the device "
+ "supports some of the sources.";
ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
flags[3] = 1;
@@ -1555,7 +1574,8 @@
}
TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
- addDevice(1, "ignored", INPUT_DEVICE_CLASS_KEYBOARD, nullptr);
+ constexpr int32_t eventHubId = 1;
+ addDevice(eventHubId, "ignored", INPUT_DEVICE_CLASS_KEYBOARD, nullptr);
NotifyConfigurationChangedArgs args;
@@ -1564,32 +1584,35 @@
}
TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
+ constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
+ constexpr int32_t eventHubId = 1;
FakeInputMapper& mapper =
- addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD,
+ addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
AINPUT_SOURCE_KEYBOARD, nullptr);
- mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, 1);
+ mFakeEventHub->enqueueEvent(0, eventHubId, EV_KEY, KEY_A, 1);
mReader->loopOnce();
ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
RawEvent event;
ASSERT_NO_FATAL_FAILURE(mapper.assertProcessWasCalled(&event));
ASSERT_EQ(0, event.when);
- ASSERT_EQ(1, event.deviceId);
+ ASSERT_EQ(eventHubId, event.deviceId);
ASSERT_EQ(EV_KEY, event.type);
ASSERT_EQ(KEY_A, event.code);
ASSERT_EQ(1, event.value);
}
TEST_F(InputReaderTest, DeviceReset_IncrementsSequenceNumber) {
- constexpr int32_t deviceId = 1;
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
- std::shared_ptr<InputDevice> device =
- mReader->newDevice(deviceId, 0 /*controllerNumber*/, "fake", deviceClass);
+ constexpr int32_t eventHubId = 1;
+ std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
// Must add at least one mapper or the device will be ignored!
- device->addMapper<FakeInputMapper>(AINPUT_SOURCE_KEYBOARD);
+ device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
mReader->setNextDevice(device);
- ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
+ ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
NotifyDeviceResetArgs resetArgs;
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
@@ -1615,12 +1638,13 @@
}
TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
- constexpr int32_t deviceId = 1;
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
+ constexpr int32_t eventHubId = 1;
const char* DEVICE_LOCATION = "USB1";
- std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, 0 /*controllerNumber*/,
- "fake", deviceClass, DEVICE_LOCATION);
- FakeInputMapper& mapper = device->addMapper<FakeInputMapper>(AINPUT_SOURCE_TOUCHSCREEN);
+ std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
+ FakeInputMapper& mapper =
+ device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_TOUCHSCREEN);
mReader->setNextDevice(device);
const uint8_t hdmi1 = 1;
@@ -1640,7 +1664,7 @@
// Add the device, and make sure all of the callbacks are triggered.
// The device is added after the input port associations are processed since
// we do not yet support dynamic device-to-display associations.
- ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
+ ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
@@ -1666,6 +1690,7 @@
static const int32_t DEVICE_GENERATION;
static const int32_t DEVICE_CONTROLLER_NUMBER;
static const uint32_t DEVICE_CLASSES;
+ static const int32_t EVENTHUB_ID;
std::shared_ptr<FakeEventHub> mFakeEventHub;
sp<FakeInputReaderPolicy> mFakePolicy;
@@ -1680,13 +1705,12 @@
mFakeListener = new TestInputListener();
mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
- mFakeEventHub->addDevice(DEVICE_ID, DEVICE_NAME, 0);
+ mFakeEventHub->addDevice(EVENTHUB_ID, DEVICE_NAME, 0);
InputDeviceIdentifier identifier;
identifier.name = DEVICE_NAME;
identifier.location = DEVICE_LOCATION;
- mDevice =
- std::make_shared<InputDevice>(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
- DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
+ mDevice = std::make_shared<InputDevice>(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
+ identifier);
}
virtual void TearDown() override {
@@ -1699,20 +1723,21 @@
const char* InputDeviceTest::DEVICE_NAME = "device";
const char* InputDeviceTest::DEVICE_LOCATION = "USB1";
-const int32_t InputDeviceTest::DEVICE_ID = 1;
+const int32_t InputDeviceTest::DEVICE_ID = END_RESERVED_ID + 1000;
const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
const uint32_t InputDeviceTest::DEVICE_CLASSES = INPUT_DEVICE_CLASS_KEYBOARD
| INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_JOYSTICK;
+const int32_t InputDeviceTest::EVENTHUB_ID = 1;
TEST_F(InputDeviceTest, ImmutableProperties) {
ASSERT_EQ(DEVICE_ID, mDevice->getId());
ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
- ASSERT_EQ(DEVICE_CLASSES, mDevice->getClasses());
+ ASSERT_EQ(0U, mDevice->getClasses());
}
-TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsTrue) {
- ASSERT_EQ(mDevice->isEnabled(), true);
+TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsFalse) {
+ ASSERT_EQ(mDevice->isEnabled(), false);
}
TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
@@ -1759,9 +1784,10 @@
TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
// Configuration.
- mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8("key"), String8("value"));
+ mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, String8("key"), String8("value"));
- FakeInputMapper& mapper1 = mDevice->addMapper<FakeInputMapper>(AINPUT_SOURCE_KEYBOARD);
+ FakeInputMapper& mapper1 =
+ mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
mapper1.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
mapper1.setMetaState(AMETA_ALT_ON);
mapper1.addSupportedKeyCode(AKEYCODE_A);
@@ -1772,7 +1798,8 @@
mapper1.setScanCodeState(3, AKEY_STATE_UP);
mapper1.setSwitchState(4, AKEY_STATE_DOWN);
- FakeInputMapper& mapper2 = mDevice->addMapper<FakeInputMapper>(AINPUT_SOURCE_TOUCHSCREEN);
+ FakeInputMapper& mapper2 =
+ mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
mapper2.setMetaState(AMETA_SHIFT_ON);
InputReaderConfiguration config;
@@ -1843,6 +1870,7 @@
// Event handling.
RawEvent event;
+ event.deviceId = EVENTHUB_ID;
mDevice->process(&event, 1);
ASSERT_NO_FATAL_FAILURE(mapper1.assertProcessWasCalled());
@@ -1853,7 +1881,7 @@
// 1. Device is disabled if the viewport corresponding to the associated display is not found
// 2. Device is disabled when setEnabled API is called
TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) {
- mDevice->addMapper<FakeInputMapper>(AINPUT_SOURCE_TOUCHSCREEN);
+ mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
// First Configuration.
mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
@@ -1902,6 +1930,7 @@
static const int32_t DEVICE_GENERATION;
static const int32_t DEVICE_CONTROLLER_NUMBER;
static const uint32_t DEVICE_CLASSES;
+ static const int32_t EVENTHUB_ID;
std::shared_ptr<FakeEventHub> mFakeEventHub;
sp<FakeInputReaderPolicy> mFakePolicy;
@@ -1909,7 +1938,7 @@
FakeInputReaderContext* mFakeContext;
InputDevice* mDevice;
- virtual void SetUp() override {
+ virtual void SetUp(uint32_t classes) {
mFakeEventHub = std::make_unique<FakeEventHub>();
mFakePolicy = new FakeInputReaderPolicy();
mFakeListener = new TestInputListener();
@@ -1917,12 +1946,13 @@
InputDeviceIdentifier identifier;
identifier.name = DEVICE_NAME;
identifier.location = DEVICE_LOCATION;
- mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
- DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
+ mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION, identifier);
- mFakeEventHub->addDevice(mDevice->getId(), DEVICE_NAME, 0);
+ mFakeEventHub->addDevice(EVENTHUB_ID, DEVICE_NAME, classes);
}
+ virtual void SetUp() override { SetUp(DEVICE_CLASSES); }
+
virtual void TearDown() override {
delete mDevice;
delete mFakeContext;
@@ -1931,7 +1961,7 @@
}
void addConfigurationProperty(const char* key, const char* value) {
- mFakeEventHub->addConfigurationProperty(mDevice->getId(), String8(key), String8(value));
+ mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, String8(key), String8(value));
}
void configureDevice(uint32_t changes) {
@@ -1940,7 +1970,7 @@
template <class T, typename... Args>
T& addMapperAndConfigure(Args... args) {
- T& mapper = mDevice->addMapper<T>(args...);
+ T& mapper = mDevice->addMapper<T>(EVENTHUB_ID, args...);
configureDevice(0);
mDevice->reset(ARBITRARY_TIME);
return mapper;
@@ -1962,7 +1992,7 @@
int32_t value) {
RawEvent event;
event.when = when;
- event.deviceId = mapper.getDeviceId();
+ event.deviceId = mapper.getDeviceContext().getEventHubId();
event.type = type;
event.code = code;
event.value = value;
@@ -2007,11 +2037,11 @@
const char* InputMapperTest::DEVICE_NAME = "device";
const char* InputMapperTest::DEVICE_LOCATION = "USB1";
-const int32_t InputMapperTest::DEVICE_ID = 1;
+const int32_t InputMapperTest::DEVICE_ID = END_RESERVED_ID + 1000;
const int32_t InputMapperTest::DEVICE_GENERATION = 2;
const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0;
const uint32_t InputMapperTest::DEVICE_CLASSES = 0; // not needed for current tests
-
+const int32_t InputMapperTest::EVENTHUB_ID = 1;
// --- SwitchInputMapperTest ---
@@ -2028,10 +2058,10 @@
TEST_F(SwitchInputMapperTest, GetSwitchState) {
SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
- mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 1);
+ mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 1);
ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
- mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 0);
+ mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 0);
ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
}
@@ -2105,8 +2135,8 @@
TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
const int32_t USAGE_A = 0x070004;
const int32_t USAGE_UNKNOWN = 0x07ffff;
- mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
- mFakeEventHub->addKey(DEVICE_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
@@ -2203,8 +2233,8 @@
}
TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
- mFakeEventHub->addKey(DEVICE_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, AKEYCODE_A, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
@@ -2242,10 +2272,10 @@
}
TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
- mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
@@ -2263,10 +2293,10 @@
}
TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
- mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
addConfigurationProperty("keyboard.orientationAware", "1");
KeyboardInputMapper& mapper =
@@ -2339,7 +2369,7 @@
TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_NotOrientationAware) {
// If the keyboard is not orientation aware,
// key events should not be associated with a specific display id
- mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
@@ -2364,7 +2394,7 @@
TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) {
// If the keyboard is orientation aware,
// key events should be associated with the internal viewport
- mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
addConfigurationProperty("keyboard.orientationAware", "1");
KeyboardInputMapper& mapper =
@@ -2399,10 +2429,10 @@
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
- mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 1);
+ mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 1);
ASSERT_EQ(1, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
- mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 0);
+ mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 0);
ASSERT_EQ(0, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
}
@@ -2411,10 +2441,10 @@
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
- mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 1);
+ mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 1);
ASSERT_EQ(1, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
- mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 0);
+ mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 0);
ASSERT_EQ(0, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
}
@@ -2423,7 +2453,7 @@
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
- mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, AKEYCODE_A, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B };
uint8_t flags[2] = { 0, 0 };
@@ -2433,99 +2463,100 @@
}
TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
- mFakeEventHub->addLed(DEVICE_ID, LED_CAPSL, true /*initially on*/);
- mFakeEventHub->addLed(DEVICE_ID, LED_NUML, false /*initially off*/);
- mFakeEventHub->addLed(DEVICE_ID, LED_SCROLLL, false /*initially off*/);
- mFakeEventHub->addKey(DEVICE_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
+ mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
+ mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
+ mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
// Initialization should have turned all of the lights off.
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
// Toggle caps lock on.
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 1);
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 0);
- ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+ ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
// Toggle num lock on.
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1);
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 0);
- ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
- ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+ ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
+ ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
// Toggle caps lock off.
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 1);
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 0);
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
- ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
+ ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
// Toggle scroll lock on.
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
- ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
- ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
+ ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
+ ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
// Toggle num lock off.
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1);
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 0);
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
- ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
+ ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
// Toggle scroll lock off.
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
- ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
+ ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
}
TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) {
// keyboard 1.
- mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
// keyboard 2.
const std::string USB2 = "USB2";
constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
+ constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
InputDeviceIdentifier identifier;
identifier.name = "KEYBOARD2";
identifier.location = USB2;
std::unique_ptr<InputDevice> device2 =
std::make_unique<InputDevice>(mFakeContext, SECOND_DEVICE_ID, DEVICE_GENERATION,
- DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
- mFakeEventHub->addDevice(SECOND_DEVICE_ID, DEVICE_NAME, 0 /*classes*/);
- mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
- mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
- mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
- mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
+ identifier);
+ mFakeEventHub->addDevice(SECOND_EVENTHUB_ID, DEVICE_NAME, 0 /*classes*/);
+ mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+ mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
+ mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
+ mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
KeyboardInputMapper& mapper2 =
- device2->addMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
+ device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/);
device2->reset(ARBITRARY_TIME);
@@ -2577,14 +2608,23 @@
AKEYCODE_DPAD_LEFT, newDisplayId));
}
-TEST_F(KeyboardInputMapperTest, ExternalDevice_WakeBehavior) {
+// --- KeyboardInputMapperTest_ExternalDevice ---
+
+class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {
+protected:
+ virtual void SetUp() override {
+ InputMapperTest::SetUp(DEVICE_CLASSES | INPUT_DEVICE_CLASS_EXTERNAL);
+ }
+};
+
+TEST_F(KeyboardInputMapperTest_ExternalDevice, WakeBehavior) {
// For external devices, non-media keys will trigger wake on key down. Media keys need to be
// marked as WAKE in the keylayout file to trigger wake.
- mDevice->setExternal(true);
- mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE,
+ POLICY_FLAG_WAKE);
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
@@ -2616,13 +2656,12 @@
ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
}
-TEST_F(KeyboardInputMapperTest, ExternalDevice_DoNotWakeByDefaultBehavior) {
+TEST_F(KeyboardInputMapperTest_ExternalDevice, DoNotWakeByDefaultBehavior) {
// Tv Remote key's wake behavior is prescribed by the keylayout file.
- mDevice->setExternal(true);
- mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
- mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
- mFakeEventHub->addKey(DEVICE_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
addConfigurationProperty("keyboard.doNotWakeByDefault", "1");
KeyboardInputMapper& mapper =
@@ -3564,10 +3603,10 @@
}
void TouchInputMapperTest::prepareVirtualKeys() {
- mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[0]);
- mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[1]);
- mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
- mFakeEventHub->addKey(DEVICE_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
+ mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[0]);
+ mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[1]);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
}
void TouchInputMapperTest::prepareLocationCalibration() {
@@ -3628,33 +3667,29 @@
};
void SingleTouchInputMapperTest::prepareButtons() {
- mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
}
void SingleTouchInputMapperTest::prepareAxes(int axes) {
if (axes & POSITION) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_X,
- RAW_X_MIN, RAW_X_MAX, 0, 0);
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_Y,
- RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
}
if (axes & PRESSURE) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_PRESSURE,
- RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MIN,
+ RAW_PRESSURE_MAX, 0, 0);
}
if (axes & TOOL) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TOOL_WIDTH,
- RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0,
+ 0);
}
if (axes & DISTANCE) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_DISTANCE,
- RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_DISTANCE, RAW_DISTANCE_MIN,
+ RAW_DISTANCE_MAX, 0, 0);
}
if (axes & TILT) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TILT_X,
- RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TILT_Y,
- RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_X, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_Y, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
}
}
@@ -3710,8 +3745,8 @@
}
TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndIsACursor_ReturnsTouchPad) {
- mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_X);
- mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_Y);
+ mFakeEventHub->addRelativeAxis(EVENTHUB_ID, REL_X);
+ mFakeEventHub->addRelativeAxis(EVENTHUB_ID, REL_Y);
prepareButtons();
prepareAxes(POSITION);
SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
@@ -4778,7 +4813,7 @@
prepareDisplay(DISPLAY_ORIENTATION_0);
prepareButtons();
prepareAxes(POSITION);
- mFakeEventHub->addKey(DEVICE_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
NotifyMotionArgs motionArgs;
@@ -4940,51 +4975,47 @@
void MultiTouchInputMapperTest::prepareAxes(int axes) {
if (axes & POSITION) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_X,
- RAW_X_MIN, RAW_X_MAX, 0, 0);
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_Y,
- RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
}
if (axes & TOUCH) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR,
- RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN,
+ RAW_TOUCH_MAX, 0, 0);
if (axes & MINOR) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
- RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN,
+ RAW_TOUCH_MAX, 0, 0);
}
}
if (axes & TOOL) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR,
- RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
+ 0, 0);
if (axes & MINOR) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
- RAW_TOOL_MAX, RAW_TOOL_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MAX,
+ RAW_TOOL_MAX, 0, 0);
}
}
if (axes & ORIENTATION) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_ORIENTATION,
- RAW_ORIENTATION_MIN, RAW_ORIENTATION_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, RAW_ORIENTATION_MIN,
+ RAW_ORIENTATION_MAX, 0, 0);
}
if (axes & PRESSURE) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_PRESSURE,
- RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, RAW_PRESSURE_MIN,
+ RAW_PRESSURE_MAX, 0, 0);
}
if (axes & DISTANCE) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_DISTANCE,
- RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_DISTANCE, RAW_DISTANCE_MIN,
+ RAW_DISTANCE_MAX, 0, 0);
}
if (axes & ID) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
- RAW_ID_MIN, RAW_ID_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX, 0,
+ 0);
}
if (axes & SLOT) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_SLOT,
- RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
- mFakeEventHub->setAbsoluteAxisValue(DEVICE_ID, ABS_MT_SLOT, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
+ mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, 0);
}
if (axes & TOOL_TYPE) {
- mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOOL_TYPE,
- 0, MT_TOOL_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
}
}
@@ -6273,7 +6304,7 @@
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(DISPLAY_ORIENTATION_0);
prepareAxes(POSITION | ID | SLOT);
- mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
NotifyMotionArgs motionArgs;
@@ -6452,35 +6483,6 @@
ASSERT_EQ(DISPLAY_ID, args.displayId);
}
-/**
- * Expect fallback to internal viewport if device is external and external viewport is not present.
- */
-TEST_F(MultiTouchInputMapperTest, Viewports_Fallback) {
- prepareAxes(POSITION);
- addConfigurationProperty("touch.deviceType", "touchScreen");
- prepareDisplay(DISPLAY_ORIENTATION_0);
- mDevice->setExternal(true);
- MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
-
- ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
-
- NotifyMotionArgs motionArgs;
-
- // Expect the event to be sent to the internal viewport,
- // because an external viewport is not present.
- processPosition(mapper, 100, 100);
- processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
- ASSERT_EQ(ADISPLAY_ID_DEFAULT, motionArgs.displayId);
-
- // Expect the event to be sent to the external viewport if it is present.
- prepareSecondaryDisplay(ViewportType::VIEWPORT_EXTERNAL);
- processPosition(mapper, 100, 100);
- processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
- ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
-}
-
TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
// Setup for second display.
sp<FakePointerController> fakePointerController = new FakePointerController();
@@ -6517,27 +6519,28 @@
// Create the second touch screen device, and enable multi fingers.
const std::string USB2 = "USB2";
constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
+ constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
InputDeviceIdentifier identifier;
identifier.name = "TOUCHSCREEN2";
identifier.location = USB2;
std::unique_ptr<InputDevice> device2 =
std::make_unique<InputDevice>(mFakeContext, SECOND_DEVICE_ID, DEVICE_GENERATION,
- DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
- mFakeEventHub->addDevice(SECOND_DEVICE_ID, DEVICE_NAME, 0 /*classes*/);
- mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
- 0 /*flat*/, 0 /*fuzz*/);
- mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
- 0 /*flat*/, 0 /*fuzz*/);
- mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
- 0 /*flat*/, 0 /*fuzz*/);
- mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
- 0 /*flat*/, 0 /*fuzz*/);
- mFakeEventHub->setAbsoluteAxisValue(SECOND_DEVICE_ID, ABS_MT_SLOT, 0 /*value*/);
- mFakeEventHub->addConfigurationProperty(SECOND_DEVICE_ID, String8("touch.deviceType"),
- String8("touchScreen"));
+ identifier);
+ mFakeEventHub->addDevice(SECOND_EVENTHUB_ID, DEVICE_NAME, 0 /*classes*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->setAbsoluteAxisValue(SECOND_EVENTHUB_ID, ABS_MT_SLOT, 0 /*value*/);
+ mFakeEventHub->addConfigurationProperty(SECOND_EVENTHUB_ID, String8("touch.deviceType"),
+ String8("touchScreen"));
// Setup the second touch screen device.
- MultiTouchInputMapper& mapper2 = device2->addMapper<MultiTouchInputMapper>();
+ MultiTouchInputMapper& mapper2 = device2->addMapper<MultiTouchInputMapper>(SECOND_EVENTHUB_ID);
device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/);
device2->reset(ARBITRARY_TIME);
@@ -6598,7 +6601,7 @@
// Unrotated video frame
TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
std::vector<TouchVideoFrame> frames{frame};
- mFakeEventHub->setVideoFrames({{mDevice->getId(), frames}});
+ mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
processPosition(mapper, 100, 200);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
@@ -6628,7 +6631,7 @@
clearViewports();
prepareDisplay(orientation);
std::vector<TouchVideoFrame> frames{frame};
- mFakeEventHub->setVideoFrames({{mDevice->getId(), frames}});
+ mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
processPosition(mapper, 100, 200);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
@@ -6650,7 +6653,7 @@
NotifyMotionArgs motionArgs;
prepareDisplay(DISPLAY_ORIENTATION_90);
- mFakeEventHub->setVideoFrames({{mDevice->getId(), frames}});
+ mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
processPosition(mapper, 100, 200);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
@@ -6824,4 +6827,41 @@
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
}
+// --- MultiTouchInputMapperTest_ExternalDevice ---
+
+class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
+protected:
+ virtual void SetUp() override {
+ InputMapperTest::SetUp(DEVICE_CLASSES | INPUT_DEVICE_CLASS_EXTERNAL);
+ }
+};
+
+/**
+ * Expect fallback to internal viewport if device is external and external viewport is not present.
+ */
+TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) {
+ prepareAxes(POSITION);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+
+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
+
+ NotifyMotionArgs motionArgs;
+
+ // Expect the event to be sent to the internal viewport,
+ // because an external viewport is not present.
+ processPosition(mapper, 100, 100);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(ADISPLAY_ID_DEFAULT, motionArgs.displayId);
+
+ // Expect the event to be sent to the external viewport if it is present.
+ prepareSecondaryDisplay(ViewportType::VIEWPORT_EXTERNAL);
+ processPosition(mapper, 100, 100);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
+}
+
} // namespace android