Refactor EventHub.
1. Remove linked list from Device.
2. Use STL containers for EventHub mDevices, mOpeningDevices,
mClosingDevices.
3. Move device operation functions to Device member functions.
Bug: 160010896
Test: atest libinput_tests, atest inputflinger_tests
Change-Id: I36f09ec93e92b9b527b38b66a3f8a3de94a3afa1
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index f19d3e5..8f34e8a 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -57,8 +57,6 @@
namespace android {
-static constexpr bool DEBUG = false;
-
static const char* DEVICE_PATH = "/dev/input";
// v4l2 devices go directly into /dev
static const char* VIDEO_DEVICE_PATH = "/dev";
@@ -171,8 +169,7 @@
EventHub::Device::Device(int fd, int32_t id, const std::string& path,
const InputDeviceIdentifier& identifier)
- : next(nullptr),
- fd(fd),
+ : fd(fd),
id(id),
path(path),
identifier(identifier),
@@ -213,10 +210,159 @@
return OK;
}
-bool EventHub::Device::hasValidFd() {
+bool EventHub::Device::hasValidFd() const {
return !isVirtual && enabled;
}
+const sp<KeyCharacterMap>& EventHub::Device::getKeyCharacterMap() const {
+ if (combinedKeyMap != nullptr) {
+ return combinedKeyMap;
+ }
+ return keyMap.keyCharacterMap;
+}
+
+template <std::size_t N>
+status_t EventHub::Device::readDeviceBitMask(unsigned long ioctlCode, BitArray<N>& bitArray) {
+ if (!hasValidFd()) {
+ return BAD_VALUE;
+ }
+ if ((_IOC_SIZE(ioctlCode) == 0)) {
+ ioctlCode |= _IOC(0, 0, 0, bitArray.bytes());
+ }
+
+ typename BitArray<N>::Buffer buffer;
+ status_t ret = ioctl(fd, ioctlCode, buffer.data());
+ bitArray.loadFromBuffer(buffer);
+ return ret;
+}
+
+void EventHub::Device::configureFd() {
+ // Set fd parameters with ioctl, such as key repeat, suspend block, and clock type
+ if (classes.test(InputDeviceClass::KEYBOARD)) {
+ // Disable kernel key repeat since we handle it ourselves
+ unsigned int repeatRate[] = {0, 0};
+ if (ioctl(fd, EVIOCSREP, repeatRate)) {
+ ALOGW("Unable to disable kernel key repeat for %s: %s", path.c_str(), strerror(errno));
+ }
+ }
+
+ // Tell the kernel that we want to use the monotonic clock for reporting timestamps
+ // associated with input events. This is important because the input system
+ // uses the timestamps extensively and assumes they were recorded using the monotonic
+ // clock.
+ int clockId = CLOCK_MONOTONIC;
+ bool usingClockIoctl = !ioctl(fd, EVIOCSCLOCKID, &clockId);
+ ALOGI("usingClockIoctl=%s", toString(usingClockIoctl));
+}
+
+bool EventHub::Device::hasKeycodeLocked(int keycode) const {
+ if (!keyMap.haveKeyLayout()) {
+ return false;
+ }
+
+ std::vector<int32_t> scanCodes;
+ keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes);
+ const size_t N = scanCodes.size();
+ for (size_t i = 0; i < N && i <= KEY_MAX; i++) {
+ int32_t sc = scanCodes[i];
+ if (sc >= 0 && sc <= KEY_MAX && keyBitmask.test(sc)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void EventHub::Device::loadConfigurationLocked() {
+ configurationFile =
+ getInputDeviceConfigurationFilePathByDeviceIdentifier(identifier,
+ InputDeviceConfigurationFileType::
+ CONFIGURATION);
+ if (configurationFile.empty()) {
+ ALOGD("No input device configuration file found for device '%s'.", identifier.name.c_str());
+ } else {
+ status_t status = PropertyMap::load(String8(configurationFile.c_str()), &configuration);
+ if (status) {
+ ALOGE("Error loading input device configuration file for device '%s'. "
+ "Using default configuration.",
+ identifier.name.c_str());
+ }
+ }
+}
+
+bool EventHub::Device::loadVirtualKeyMapLocked() {
+ // The virtual key map is supplied by the kernel as a system board property file.
+ std::string propPath = "/sys/board_properties/virtualkeys.";
+ propPath += identifier.getCanonicalName();
+ if (access(propPath.c_str(), R_OK)) {
+ return false;
+ }
+ virtualKeyMap = VirtualKeyMap::load(propPath);
+ return virtualKeyMap != nullptr;
+}
+
+status_t EventHub::Device::loadKeyMapLocked() {
+ return keyMap.load(identifier, configuration);
+}
+
+bool EventHub::Device::isExternalDeviceLocked() {
+ if (configuration) {
+ bool value;
+ if (configuration->tryGetProperty(String8("device.internal"), value)) {
+ return !value;
+ }
+ }
+ return identifier.bus == BUS_USB || identifier.bus == BUS_BLUETOOTH;
+}
+
+bool EventHub::Device::deviceHasMicLocked() {
+ if (configuration) {
+ bool value;
+ if (configuration->tryGetProperty(String8("audio.mic"), value)) {
+ return value;
+ }
+ }
+ return false;
+}
+
+void EventHub::Device::setLedStateLocked(int32_t led, bool on) {
+ int32_t sc;
+ if (hasValidFd() && mapLed(led, &sc) != NAME_NOT_FOUND) {
+ struct input_event ev;
+ ev.time.tv_sec = 0;
+ ev.time.tv_usec = 0;
+ ev.type = EV_LED;
+ ev.code = sc;
+ ev.value = on ? 1 : 0;
+
+ ssize_t nWrite;
+ do {
+ nWrite = write(fd, &ev, sizeof(struct input_event));
+ } while (nWrite == -1 && errno == EINTR);
+ }
+}
+
+void EventHub::Device::setLedForControllerLocked() {
+ for (int i = 0; i < MAX_CONTROLLER_LEDS; i++) {
+ setLedStateLocked(ALED_CONTROLLER_1 + i, controllerNumber == i + 1);
+ }
+}
+
+status_t EventHub::Device::mapLed(int32_t led, int32_t* outScanCode) const {
+ if (!keyMap.haveKeyLayout()) {
+ return NAME_NOT_FOUND;
+ }
+
+ int32_t scanCode;
+ if (keyMap.keyLayoutMap->findScanCodeForLed(led, &scanCode) != NAME_NOT_FOUND) {
+ if (scanCode >= 0 && scanCode <= LED_MAX && ledBitmask.test(scanCode)) {
+ *outScanCode = scanCode;
+ return NO_ERROR;
+ }
+ }
+ return NAME_NOT_FOUND;
+}
+
/**
* Get the capabilities for the current process.
* Crashes the system if unable to create / check / destroy the capabilities object.
@@ -266,8 +412,8 @@
: mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD),
mNextDeviceId(1),
mControllerNumbers(),
- mOpeningDevices(nullptr),
- mClosingDevices(nullptr),
+ mOpeningDevices(0),
+ mClosingDevices(0),
mNeedToSendFinishedDeviceScan(false),
mNeedToReopenDevices(false),
mNeedToScanDevices(true),
@@ -322,11 +468,7 @@
EventHub::~EventHub(void) {
closeAllDevicesLocked();
- while (mClosingDevices) {
- Device* device = mClosingDevices;
- mClosingDevices = device->next;
- delete device;
- }
+ mClosingDevices.clear();
::close(mEpollFd);
::close(mINotifyFd);
@@ -337,30 +479,25 @@
InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device == nullptr) return InputDeviceIdentifier();
- return device->identifier;
+ return device != nullptr ? device->identifier : InputDeviceIdentifier();
}
Flags<InputDeviceClass> EventHub::getDeviceClasses(int32_t deviceId) const {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device == nullptr) {
- return Flags<InputDeviceClass>(0);
- }
- return device->classes;
+ return device != nullptr ? device->classes : Flags<InputDeviceClass>(0);
}
int32_t EventHub::getDeviceControllerNumber(int32_t deviceId) const {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device == nullptr) return 0;
- return device->controllerNumber;
+ return device != nullptr ? device->controllerNumber : 0;
}
void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device && device->configuration) {
+ if (device != nullptr && device->configuration) {
*outConfiguration = *device->configuration;
} else {
outConfiguration->clear();
@@ -400,7 +537,6 @@
bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const {
if (axis >= 0 && axis <= REL_MAX) {
AutoMutex _l(mLock);
-
Device* device = getDeviceLocked(deviceId);
return device != nullptr ? device->relBitmask.test(axis) : false;
}
@@ -408,13 +544,12 @@
}
bool EventHub::hasInputProperty(int32_t deviceId, int property) const {
- if (property >= 0 && property <= INPUT_PROP_MAX) {
- AutoMutex _l(mLock);
+ AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- return device != nullptr ? device->propBitmask.test(property) : false;
- }
- return false;
+ Device* device = getDeviceLocked(deviceId);
+ return property >= 0 && property <= INPUT_PROP_MAX && device != nullptr
+ ? device->propBitmask.test(property)
+ : false;
}
int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
@@ -591,7 +726,7 @@
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
int32_t sc;
- if (device != nullptr && mapLed(device, led, &sc) == NO_ERROR) {
+ if (device != nullptr && device->mapLed(led, &sc) == NO_ERROR) {
return device->ledBitmask.test(sc);
}
return false;
@@ -600,23 +735,8 @@
void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- setLedStateLocked(device, led, on);
-}
-
-void EventHub::setLedStateLocked(Device* device, int32_t led, bool on) {
- int32_t sc;
- if (device != nullptr && device->hasValidFd() && mapLed(device, led, &sc) != NAME_NOT_FOUND) {
- struct input_event ev;
- ev.time.tv_sec = 0;
- ev.time.tv_usec = 0;
- ev.type = EV_LED;
- ev.code = sc;
- ev.value = on ? 1 : 0;
-
- ssize_t nWrite;
- do {
- nWrite = write(device->fd, &ev, sizeof(struct input_event));
- } while (nWrite == -1 && errno == EINTR);
+ if (device != nullptr && device->hasValidFd()) {
+ device->setLedStateLocked(led, on);
}
}
@@ -763,11 +883,9 @@
}
EventHub::Device* EventHub::getDeviceByDescriptorLocked(const std::string& descriptor) const {
- size_t size = mDevices.size();
- for (size_t i = 0; i < size; i++) {
- Device* device = mDevices.valueAt(i);
+ for (const auto& [id, device] : mDevices) {
if (descriptor == device->identifier.descriptor) {
- return device;
+ return device.get();
}
}
return nullptr;
@@ -777,15 +895,14 @@
if (deviceId == ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID) {
deviceId = mBuiltInKeyboardId;
}
- ssize_t index = mDevices.indexOfKey(deviceId);
- return index >= 0 ? mDevices.valueAt(index) : NULL;
+ const auto& it = mDevices.find(deviceId);
+ return it != mDevices.end() ? it->second.get() : nullptr;
}
EventHub::Device* EventHub::getDeviceByPathLocked(const std::string& devicePath) const {
- for (size_t i = 0; i < mDevices.size(); i++) {
- Device* device = mDevices.valueAt(i);
+ for (const auto& [id, device] : mDevices) {
if (device->path == devicePath) {
- return device;
+ return device.get();
}
}
return nullptr;
@@ -799,15 +916,14 @@
* devices are ignored.
*/
EventHub::Device* EventHub::getDeviceByFdLocked(int fd) const {
- for (size_t i = 0; i < mDevices.size(); i++) {
- Device* device = mDevices.valueAt(i);
+ for (const auto& [id, device] : mDevices) {
if (device->fd == fd) {
// This is an input device event
- return device;
+ return device.get();
}
if (device->videoDevice && device->videoDevice->getFd() == fd) {
// This is a video device event
- return device;
+ return device.get();
}
}
// We do not check mUnattachedVideoDevices here because they should not participate in epoll,
@@ -840,17 +956,16 @@
}
// Report any devices that had last been added/removed.
- while (mClosingDevices) {
- Device* device = mClosingDevices;
+ for (auto it = mClosingDevices.begin(); it != mClosingDevices.end();) {
+ std::unique_ptr<Device> device = std::move(*it);
ALOGV("Reporting device closed: id=%d, name=%s\n", device->id, device->path.c_str());
- mClosingDevices = device->next;
event->when = now;
event->deviceId = (device->id == mBuiltInKeyboardId)
? ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID
: device->id;
event->type = DEVICE_REMOVED;
event += 1;
- delete device;
+ it = mClosingDevices.erase(it);
mNeedToSendFinishedDeviceScan = true;
if (--capacity == 0) {
break;
@@ -863,14 +978,18 @@
mNeedToSendFinishedDeviceScan = true;
}
- while (mOpeningDevices != nullptr) {
- Device* device = mOpeningDevices;
+ for (auto it = mOpeningDevices.begin(); it != mOpeningDevices.end();) {
+ std::unique_ptr<Device> device = std::move(*it);
ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.c_str());
- mOpeningDevices = device->next;
event->when = now;
event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
event->type = DEVICE_ADDED;
event += 1;
+ auto [dev_it, insert] = mDevices.insert_or_assign(device->id, std::move(device));
+ if (!insert) {
+ ALOGW("Device id %d exists, replaced.", device->id);
+ }
+ it = mOpeningDevices.erase(it);
mNeedToSendFinishedDeviceScan = true;
if (--capacity == 0) {
break;
@@ -917,7 +1036,7 @@
}
Device* device = getDeviceByFdLocked(eventItem.data.fd);
- if (!device) {
+ if (device == nullptr) {
ALOGE("Received unexpected epoll event 0x%08x for unknown fd %d.", eventItem.events,
eventItem.data.fd);
ALOG_ASSERT(!DEBUG);
@@ -953,7 +1072,7 @@
" bufferSize: %zu capacity: %zu errno: %d)\n",
device->fd, readSize, bufferSize, capacity, errno);
deviceChanged = true;
- closeDeviceLocked(device);
+ closeDeviceLocked(*device);
} else if (readSize < 0) {
if (errno != EAGAIN && errno != EINTR) {
ALOGW("could not get event (errno=%d)", errno);
@@ -985,7 +1104,7 @@
ALOGI("Removing device %s due to epoll hang-up event.",
device->identifier.name.c_str());
deviceChanged = true;
- closeDeviceLocked(device);
+ closeDeviceLocked(*device);
} else {
ALOGW("Received unexpected epoll event 0x%08x for device %s.", eventItem.events,
device->identifier.name.c_str());
@@ -1090,7 +1209,7 @@
ALOGE("scan video dir failed for %s", VIDEO_DEVICE_PATH);
}
}
- if (mDevices.indexOfKey(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID) < 0) {
+ if (mDevices.find(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID) == mDevices.end()) {
createVirtualKeyboardLocked();
}
}
@@ -1126,20 +1245,14 @@
return OK;
}
-status_t EventHub::registerDeviceForEpollLocked(Device* device) {
- if (device == nullptr) {
- if (DEBUG) {
- LOG_ALWAYS_FATAL("Cannot call registerDeviceForEpollLocked with null Device");
- }
- return BAD_VALUE;
- }
- status_t result = registerFdForEpoll(device->fd);
+status_t EventHub::registerDeviceForEpollLocked(Device& device) {
+ status_t result = registerFdForEpoll(device.fd);
if (result != OK) {
- ALOGE("Could not add input device fd to epoll for device %" PRId32, device->id);
+ ALOGE("Could not add input device fd to epoll for device %" PRId32, device.id);
return result;
}
- if (device->videoDevice) {
- registerVideoDeviceForEpollLocked(*device->videoDevice);
+ if (device.videoDevice) {
+ registerVideoDeviceForEpollLocked(*device.videoDevice);
}
return result;
}
@@ -1151,16 +1264,16 @@
}
}
-status_t EventHub::unregisterDeviceFromEpollLocked(Device* device) {
- if (device->hasValidFd()) {
- status_t result = unregisterFdFromEpoll(device->fd);
+status_t EventHub::unregisterDeviceFromEpollLocked(Device& device) {
+ if (device.hasValidFd()) {
+ status_t result = unregisterFdFromEpoll(device.fd);
if (result != OK) {
- ALOGW("Could not remove input device fd from epoll for device %" PRId32, device->id);
+ ALOGW("Could not remove input device fd from epoll for device %" PRId32, device.id);
return result;
}
}
- if (device->videoDevice) {
- unregisterVideoDeviceFromEpollLocked(*device->videoDevice);
+ if (device.videoDevice) {
+ unregisterVideoDeviceFromEpollLocked(*device.videoDevice);
}
return OK;
}
@@ -1247,7 +1360,7 @@
// Allocate device. (The device object takes ownership of the fd at this point.)
int32_t deviceId = mNextDeviceId++;
- Device* device = new Device(fd, deviceId, devicePath, identifier);
+ std::unique_ptr<Device> device = std::make_unique<Device>(fd, deviceId, devicePath, identifier);
ALOGV("add device %d: %s\n", deviceId, devicePath.c_str());
ALOGV(" bus: %04x\n"
@@ -1263,7 +1376,7 @@
driverVersion & 0xff);
// Load the configuration file for the device.
- loadConfigurationLocked(device);
+ device->loadConfigurationLocked();
// Figure out the kinds of events the device reports.
device->readDeviceBitMask(EVIOCGBIT(EV_KEY, 0), device->keyBitmask);
@@ -1353,7 +1466,7 @@
if ((device->classes.test(InputDeviceClass::TOUCH))) {
// Load the virtual keys for the touch screen, if any.
// We do this now so that we can make sure to load the keymap if necessary.
- bool success = loadVirtualKeyMapLocked(device);
+ bool success = device->loadVirtualKeyMapLocked();
if (success) {
device->classes |= InputDeviceClass::KEYBOARD;
}
@@ -1364,7 +1477,7 @@
status_t keyMapStatus = NAME_NOT_FOUND;
if (device->classes.any(InputDeviceClass::KEYBOARD | InputDeviceClass::JOYSTICK)) {
// Load the keymap for the device.
- keyMapStatus = loadKeyMapLocked(device);
+ keyMapStatus = device->loadKeyMapLocked();
}
// Configure the keyboard, gamepad or virtual keyboard.
@@ -1376,22 +1489,22 @@
}
// 'Q' key support = cheap test of whether this is an alpha-capable kbd
- if (hasKeycodeLocked(device, AKEYCODE_Q)) {
+ if (device->hasKeycodeLocked(AKEYCODE_Q)) {
device->classes |= InputDeviceClass::ALPHAKEY;
}
// See if this device has a DPAD.
- if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) &&
- hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) &&
- hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) &&
- hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) &&
- hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) {
+ if (device->hasKeycodeLocked(AKEYCODE_DPAD_UP) &&
+ device->hasKeycodeLocked(AKEYCODE_DPAD_DOWN) &&
+ device->hasKeycodeLocked(AKEYCODE_DPAD_LEFT) &&
+ device->hasKeycodeLocked(AKEYCODE_DPAD_RIGHT) &&
+ device->hasKeycodeLocked(AKEYCODE_DPAD_CENTER)) {
device->classes |= InputDeviceClass::DPAD;
}
// See if this device has a gamepad.
for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES) / sizeof(GAMEPAD_KEYCODES[0]); i++) {
- if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) {
+ if (device->hasKeycodeLocked(GAMEPAD_KEYCODES[i])) {
device->classes |= InputDeviceClass::GAMEPAD;
break;
}
@@ -1402,24 +1515,23 @@
if (device->classes == Flags<InputDeviceClass>(0)) {
ALOGV("Dropping device: id=%d, path='%s', name='%s'", deviceId, devicePath.c_str(),
device->identifier.name.c_str());
- delete device;
return -1;
}
// Determine whether the device has a mic.
- if (deviceHasMicLocked(device)) {
+ if (device->deviceHasMicLocked()) {
device->classes |= InputDeviceClass::MIC;
}
// Determine whether the device is external or internal.
- if (isExternalDeviceLocked(device)) {
+ if (device->isExternalDeviceLocked()) {
device->classes |= InputDeviceClass::EXTERNAL;
}
if (device->classes.any(InputDeviceClass::JOYSTICK | InputDeviceClass::DPAD) &&
device->classes.test(InputDeviceClass::GAMEPAD)) {
- device->controllerNumber = getNextControllerNumberLocked(device);
- setLedForControllerLocked(device);
+ device->controllerNumber = getNextControllerNumberLocked(device->identifier.name);
+ device->setLedForControllerLocked();
}
// Find a matching video device by comparing device names
@@ -1437,12 +1549,11 @@
}),
mUnattachedVideoDevices.end());
- if (registerDeviceForEpollLocked(device) != OK) {
- delete device;
+ if (registerDeviceForEpollLocked(*device) != OK) {
return -1;
}
- configureFd(device);
+ device->configureFd();
ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=%s, "
"configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, ",
@@ -1451,30 +1562,10 @@
device->keyMap.keyLayoutFile.c_str(), device->keyMap.keyCharacterMapFile.c_str(),
toString(mBuiltInKeyboardId == deviceId));
- addDeviceLocked(device);
+ addDeviceLocked(std::move(device));
return OK;
}
-void EventHub::configureFd(Device* device) {
- // Set fd parameters with ioctl, such as key repeat, suspend block, and clock type
- if (device->classes.test(InputDeviceClass::KEYBOARD)) {
- // Disable kernel key repeat since we handle it ourselves
- unsigned int repeatRate[] = {0, 0};
- if (ioctl(device->fd, EVIOCSREP, repeatRate)) {
- ALOGW("Unable to disable kernel key repeat for %s: %s", device->path.c_str(),
- strerror(errno));
- }
- }
-
- // Tell the kernel that we want to use the monotonic clock for reporting timestamps
- // associated with input events. This is important because the input system
- // uses the timestamps extensively and assumes they were recorded using the monotonic
- // clock.
- int clockId = CLOCK_MONOTONIC;
- bool usingClockIoctl = !ioctl(device->fd, EVIOCSCLOCKID, &clockId);
- ALOGI("usingClockIoctl=%s", toString(usingClockIoctl));
-}
-
void EventHub::openVideoDeviceLocked(const std::string& devicePath) {
std::unique_ptr<TouchVideoDevice> videoDevice = TouchVideoDevice::create(devicePath);
if (!videoDevice) {
@@ -1482,8 +1573,7 @@
return;
}
// Transfer ownership of this video device to a matching input device
- for (size_t i = 0; i < mDevices.size(); i++) {
- Device* device = mDevices.valueAt(i);
+ for (const auto& [id, device] : mDevices) {
if (videoDevice->getName() == device->identifier.name) {
device->videoDevice = std::move(videoDevice);
if (device->enabled) {
@@ -1527,9 +1617,9 @@
return result;
}
- configureFd(device);
+ device->configureFd();
- return registerDeviceForEpollLocked(device);
+ return registerDeviceForEpollLocked(*device);
}
status_t EventHub::disableDevice(int32_t deviceId) {
@@ -1543,7 +1633,7 @@
ALOGW("Duplicate call to %s, input device already disabled", __func__);
return OK;
}
- unregisterDeviceFromEpollLocked(device);
+ unregisterDeviceFromEpollLocked(*device);
return device->disable();
}
@@ -1553,79 +1643,23 @@
identifier.uniqueId = "<virtual>";
assignDescriptorLocked(identifier);
- Device* device =
- new Device(-1, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, "<virtual>", identifier);
+ std::unique_ptr<Device> device =
+ std::make_unique<Device>(-1, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, "<virtual>",
+ identifier);
device->classes = InputDeviceClass::KEYBOARD | InputDeviceClass::ALPHAKEY |
InputDeviceClass::DPAD | InputDeviceClass::VIRTUAL;
- loadKeyMapLocked(device);
- addDeviceLocked(device);
+ device->loadKeyMapLocked();
+ addDeviceLocked(std::move(device));
}
-void EventHub::addDeviceLocked(Device* device) {
- mDevices.add(device->id, device);
- device->next = mOpeningDevices;
- mOpeningDevices = device;
+void EventHub::addDeviceLocked(std::unique_ptr<Device> device) {
+ mOpeningDevices.push_back(std::move(device));
}
-void EventHub::loadConfigurationLocked(Device* device) {
- device->configurationFile =
- getInputDeviceConfigurationFilePathByDeviceIdentifier(device->identifier,
- InputDeviceConfigurationFileType::
- CONFIGURATION);
- if (device->configurationFile.empty()) {
- ALOGD("No input device configuration file found for device '%s'.",
- device->identifier.name.c_str());
- } else {
- status_t status = PropertyMap::load(String8(device->configurationFile.c_str()),
- &device->configuration);
- if (status) {
- ALOGE("Error loading input device configuration file for device '%s'. "
- "Using default configuration.",
- device->identifier.name.c_str());
- }
- }
-}
-
-bool EventHub::loadVirtualKeyMapLocked(Device* device) {
- // The virtual key map is supplied by the kernel as a system board property file.
- std::string path;
- path += "/sys/board_properties/virtualkeys.";
- path += device->identifier.getCanonicalName();
- if (access(path.c_str(), R_OK)) {
- return false;
- }
- device->virtualKeyMap = VirtualKeyMap::load(path);
- return device->virtualKeyMap != nullptr;
-}
-
-status_t EventHub::loadKeyMapLocked(Device* device) {
- return device->keyMap.load(device->identifier, device->configuration);
-}
-
-bool EventHub::isExternalDeviceLocked(Device* device) {
- if (device->configuration) {
- bool value;
- if (device->configuration->tryGetProperty(String8("device.internal"), value)) {
- return !value;
- }
- }
- return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH;
-}
-
-bool EventHub::deviceHasMicLocked(Device* device) {
- if (device->configuration) {
- bool value;
- if (device->configuration->tryGetProperty(String8("audio.mic"), value)) {
- return value;
- }
- }
- return false;
-}
-
-int32_t EventHub::getNextControllerNumberLocked(Device* device) {
+int32_t EventHub::getNextControllerNumberLocked(const std::string& name) {
if (mControllerNumbers.isFull()) {
ALOGI("Maximum number of controllers reached, assigning controller number 0 to device %s",
- device->identifier.name.c_str());
+ name.c_str());
return 0;
}
// Since the controller number 0 is reserved for non-controllers, translate all numbers up by
@@ -1633,58 +1667,16 @@
return static_cast<int32_t>(mControllerNumbers.markFirstUnmarkedBit() + 1);
}
-void EventHub::releaseControllerNumberLocked(Device* device) {
- int32_t num = device->controllerNumber;
- device->controllerNumber = 0;
- if (num == 0) {
- return;
+void EventHub::releaseControllerNumberLocked(int32_t num) {
+ if (num > 0) {
+ mControllerNumbers.clearBit(static_cast<uint32_t>(num - 1));
}
- mControllerNumbers.clearBit(static_cast<uint32_t>(num - 1));
-}
-
-void EventHub::setLedForControllerLocked(Device* device) {
- for (int i = 0; i < MAX_CONTROLLER_LEDS; i++) {
- setLedStateLocked(device, ALED_CONTROLLER_1 + i, device->controllerNumber == i + 1);
- }
-}
-
-bool EventHub::hasKeycodeLocked(Device* device, int keycode) const {
- if (!device->keyMap.haveKeyLayout()) {
- return false;
- }
-
- std::vector<int32_t> scanCodes;
- device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes);
- const size_t N = scanCodes.size();
- for (size_t i = 0; i < N && i <= KEY_MAX; i++) {
- int32_t sc = scanCodes[i];
- if (sc >= 0 && sc <= KEY_MAX && device->keyBitmask.test(sc)) {
- return true;
- }
- }
-
- return false;
-}
-
-status_t EventHub::mapLed(Device* device, int32_t led, int32_t* outScanCode) const {
- if (!device->keyMap.haveKeyLayout()) {
- return NAME_NOT_FOUND;
- }
-
- int32_t scanCode;
- if (device->keyMap.keyLayoutMap->findScanCodeForLed(led, &scanCode) != NAME_NOT_FOUND) {
- if (scanCode >= 0 && scanCode <= LED_MAX && device->ledBitmask.test(scanCode)) {
- *outScanCode = scanCode;
- return NO_ERROR;
- }
- }
- return NAME_NOT_FOUND;
}
void EventHub::closeDeviceByPathLocked(const std::string& devicePath) {
Device* device = getDeviceByPathLocked(devicePath);
- if (device) {
- closeDeviceLocked(device);
+ if (device != nullptr) {
+ closeDeviceLocked(*device);
return;
}
ALOGV("Remove device: %s not found, device may already have been removed.", devicePath.c_str());
@@ -1698,8 +1690,7 @@
void EventHub::closeVideoDeviceByPathLocked(const std::string& devicePath) {
// A video device may be owned by an existing input device, or it may be stored in
// the mUnattachedVideoDevices queue. Check both locations.
- for (size_t i = 0; i < mDevices.size(); i++) {
- Device* device = mDevices.valueAt(i);
+ for (const auto& [id, device] : mDevices) {
if (device->videoDevice && device->videoDevice->getPath() == devicePath) {
unregisterVideoDeviceFromEpollLocked(*device->videoDevice);
device->videoDevice = nullptr;
@@ -1717,61 +1708,34 @@
void EventHub::closeAllDevicesLocked() {
mUnattachedVideoDevices.clear();
- while (mDevices.size() > 0) {
- closeDeviceLocked(mDevices.valueAt(mDevices.size() - 1));
+ for (const auto& [id, device] : mDevices) {
+ closeDeviceLocked(*device);
}
}
-void EventHub::closeDeviceLocked(Device* device) {
- ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=%s", device->path.c_str(),
- device->identifier.name.c_str(), device->id, device->fd,
- device->classes.string().c_str());
+void EventHub::closeDeviceLocked(Device& device) {
+ ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=%s", device.path.c_str(),
+ device.identifier.name.c_str(), device.id, device.fd, device.classes.string().c_str());
- if (device->id == mBuiltInKeyboardId) {
+ if (device.id == mBuiltInKeyboardId) {
ALOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
- device->path.c_str(), mBuiltInKeyboardId);
+ device.path.c_str(), mBuiltInKeyboardId);
mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD;
}
unregisterDeviceFromEpollLocked(device);
- if (device->videoDevice) {
+ if (device.videoDevice) {
// This must be done after the video device is removed from epoll
- mUnattachedVideoDevices.push_back(std::move(device->videoDevice));
+ mUnattachedVideoDevices.push_back(std::move(device.videoDevice));
}
- releaseControllerNumberLocked(device);
+ releaseControllerNumberLocked(device.controllerNumber);
+ device.close();
- mDevices.removeItem(device->id);
- device->close();
-
- // Unlink for opening devices list if it is present.
- Device* pred = nullptr;
- bool found = false;
- for (Device* entry = mOpeningDevices; entry != nullptr;) {
- if (entry == device) {
- found = true;
- break;
- }
- pred = entry;
- entry = entry->next;
- }
- if (found) {
- // Unlink the device from the opening devices list then delete it.
- // We don't need to tell the client that the device was closed because
- // it does not even know it was opened in the first place.
- ALOGI("Device %s was immediately closed after opening.", device->path.c_str());
- if (pred) {
- pred->next = device->next;
- } else {
- mOpeningDevices = device->next;
- }
- delete device;
- } else {
- // Link into closing devices list.
- // The device will be deleted later after we have informed the client.
- device->next = mClosingDevices;
- mClosingDevices = device;
- }
+ // Move device to mClosingDevices
+ mClosingDevices.push_back(std::move(mDevices[device.id]));
+ // Erase device from mDevices
+ mDevices.erase(device.id);
}
status_t EventHub::readNotifyLocked() {
@@ -1858,8 +1822,7 @@
dump += INDENT "Devices:\n";
- for (size_t i = 0; i < mDevices.size(); i++) {
- const Device* device = mDevices.valueAt(i);
+ for (const auto& [id, device] : mDevices) {
if (mBuiltInKeyboardId == device->id) {
dump += StringPrintf(INDENT2 "%d: %s (aka device 0 - built-in keyboard)\n",
device->id, device->identifier.name.c_str());