Fix handling of symlinked device descriptors in keyboard_remote and move remaining sync io to executor thread pool (#30206)

* fix handling of symlinked device decriptors

* make check for symlinked paths more efficient

* make variable names pylint compliant

* move sync io during setup and device connect/disconnect to executor thread pool

* move remaining sync io during setup to executor thread pool

* remove unnecessary lambda functions
This commit is contained in:
Josh Bendavid 2019-12-26 13:06:57 -05:00 committed by Martin Hjelmare
parent b2753b7578
commit d6744fbc4e

View File

@ -2,6 +2,7 @@
# pylint: disable=import-error
import asyncio
import logging
import os
import aionotify
from evdev import InputDevice, categorize, ecodes, list_devices
@ -119,9 +120,11 @@ class KeyboardRemote:
# add initial devices (do this AFTER starting watcher in order to
# avoid race conditions leading to missing device connections)
initial_start_monitoring = set()
descriptors = list_devices(DEVINPUT)
descriptors = await self.hass.async_add_executor_job(list_devices, DEVINPUT)
for descriptor in descriptors:
dev, handler = self.get_device_handler(descriptor)
dev, handler = await self.hass.async_add_executor_job(
self.get_device_handler, descriptor
)
if handler is None:
continue
@ -165,6 +168,15 @@ class KeyboardRemote:
handler = self.handlers_by_descriptor[descriptor]
elif dev.name in self.handlers_by_name:
handler = self.handlers_by_name[dev.name]
else:
# check for symlinked paths matching descriptor
for test_descriptor, test_handler in self.handlers_by_descriptor.items():
if test_handler.dev is not None:
fullpath = test_handler.dev.path
else:
fullpath = os.path.realpath(test_descriptor)
if fullpath == descriptor:
handler = test_handler
return (dev, handler)
@ -186,7 +198,9 @@ class KeyboardRemote:
(event.flags & aionotify.Flags.CREATE)
or (event.flags & aionotify.Flags.ATTRIB)
) and not descriptor_active:
dev, handler = self.get_device_handler(descriptor)
dev, handler = await self.hass.async_add_executor_job(
self.get_device_handler, descriptor
)
if handler is None:
continue
self.active_handlers_by_descriptor[descriptor] = handler
@ -242,7 +256,7 @@ class KeyboardRemote:
"""Stop event monitoring task and issue event."""
if self.monitor_task is not None:
try:
self.dev.ungrab()
await self.hass.async_add_executor_job(self.dev.ungrab)
except OSError:
pass
# monitoring of the device form the event loop and closing of the
@ -272,7 +286,7 @@ class KeyboardRemote:
try:
_LOGGER.debug("Start device monitoring")
dev.grab()
await self.hass.async_add_executor_job(dev.grab)
async for event in dev.async_read_loop():
if event.type is ecodes.EV_KEY:
if event.value in self.key_values: