Skip to content

Commit

Permalink
fix(Config): only return a match if a whole config block matches
Browse files Browse the repository at this point in the history
- also fix source device id tracking on add/remove of source device
  • Loading branch information
ShadowApex authored and Derek J. Clark committed Mar 10, 2024
1 parent 2af1113 commit 3ec9eeb
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 47 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ IMAGE_TAG ?= latest

# systemd-sysext variables
SYSEXT_ID ?= steamos
SYSEXT_VERSION_ID ?= 3.5.15
SYSEXT_VERSION_ID ?= 3.5.17

# Include any user defined settings
-include settings.mk
Expand Down
29 changes: 11 additions & 18 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,36 +168,32 @@ impl CompositeDeviceConfig {

/// Returns true if a given hidraw device is within a list of hidraw configs.
pub fn has_matching_hidraw(&self, device: &DeviceInfo, hidraw_configs: &Vec<Hidraw>) -> bool {
log::debug!("Checking hidraw config: {:?}", hidraw_configs);
for hidraw_config in hidraw_configs.clone() {
let hidraw_config = hidraw_config.clone();
let mut has_matches = false;

if let Some(vendor_id) = hidraw_config.vendor_id {
if device.vendor_id() != vendor_id {
continue;
}
has_matches = true;
}

if let Some(product_id) = hidraw_config.product_id {
if device.product_id() != product_id {
continue;
}
has_matches = true;
}

if let Some(interface_num) = hidraw_config.interface_num {
if device.interface_number() != interface_num {
continue;
}
has_matches = true;
}

if !has_matches {
return false;
}
return true;
}
return true;

false
}

/// Returns true if a given evdev device is within a list of evdev configs.
Expand All @@ -208,58 +204,55 @@ impl CompositeDeviceConfig {
) -> bool {
// TODO: Maybe in the future we will support virtual devices if we figure something
// out. Ignore virtual devices.
if is_virtual(&device) {
if is_virtual(device) {
log::debug!("{} is virtual, skipping.", device.name);
return false;
}

let mut has_matches = false;
for evdev_config in evdev_configs.clone() {
let evdev_config = evdev_config.clone();

if let Some(name) = evdev_config.name {
if !glob_match(name.as_str(), device.name.as_str()) {
continue;
}
has_matches = true;
}

if let Some(phys_path) = evdev_config.phys_path {
if !glob_match(phys_path.as_str(), device.phys_path.as_str()) {
continue;
}
has_matches = true;
}

if let Some(handler) = evdev_config.handler {
let mut has_matches = false;
for handle in device.handlers.clone() {
if !glob_match(handler.as_str(), handle.as_str()) {
continue;
}
has_matches = true;
}
if !has_matches {
continue;
}
}

if let Some(vendor_id) = evdev_config.vendor_id {
if !glob_match(vendor_id.as_str(), device.id.vendor.as_str()) {
continue;
}
has_matches = true
}

if let Some(product_id) = evdev_config.product_id {
if !glob_match(product_id.as_str(), device.id.product.as_str()) {
continue;
}
has_matches = true
}
}

if !has_matches {
return false;
return true;
}

return true;
false
}

/// Returns true if the configuration has a valid set of matches. This will
Expand Down
15 changes: 12 additions & 3 deletions src/input/composite_device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,13 +334,18 @@ impl CompositeDevice {
}
}
}
log::debug!("CompositeDevice stopped");
log::info!(
"CompositeDevice stopping: {}",
self.dbus_path.as_ref().unwrap()
);

// Stop all target devices
log::debug!("Stopping target devices");
#[allow(clippy::for_kv_map)]
for (_, target) in &self.target_devices {
target.send(TargetCommand::Stop).await?;
}
#[allow(clippy::for_kv_map)]
for (_, target) in &self.target_dbus_devices {
target.send(TargetCommand::Stop).await?;
}
Expand All @@ -359,7 +364,10 @@ impl CompositeDevice {
res?;
}

log::debug!("All source devices have closed");
log::info!(
"CompositeDevice stopped: {}",
self.dbus_path.as_ref().unwrap()
);

Ok(())
}
Expand Down Expand Up @@ -833,7 +841,8 @@ impl CompositeDevice {

self.source_device_ids.remove(idx);
}
return Ok(());

Ok(())
}

fn add_source_device(&mut self, device_info: SourceDeviceInfo) -> Result<(), Box<dyn Error>> {
Expand Down
75 changes: 50 additions & 25 deletions src/input/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::collections::HashMap;
use std::error::Error;
use std::fs;

use log::logger;
use tokio::sync::broadcast;
use tokio::sync::mpsc;
use zbus::fdo;
Expand Down Expand Up @@ -43,7 +42,7 @@ const BUFFER_SIZE: usize = 1024;
/// dispatched as they come in.
#[derive(Debug, Clone)]
pub enum Command {
SourceDeviceAdded(SourceDeviceInfo),
SourceDeviceAdded { id: String, info: SourceDeviceInfo },
SourceDeviceRemoved { id: String },
EventDeviceAdded { name: String },
EventDeviceRemoved { name: String },
Expand Down Expand Up @@ -191,8 +190,8 @@ impl Manager {
log::error!("Error creating composite device: {:?}", e);
}
}
Command::SourceDeviceAdded(device) => {
if let Err(e) = self.on_source_device_added(device).await {
Command::SourceDeviceAdded { id, info } => {
if let Err(e) = self.on_source_device_added(id, info).await {
log::error!("Error handling added source device: {:?}", e);
}
}
Expand All @@ -209,6 +208,8 @@ impl Manager {
}
}

log::info!("Stopped input manager");

Ok(())
}

Expand Down Expand Up @@ -458,6 +459,7 @@ impl Manager {
/// will be created and started.
async fn on_source_device_added(
&mut self,
id: String,
device_info: SourceDeviceInfo,
) -> Result<(), Box<dyn Error>> {
// Check all existing composite devices to see if this device is part of
Expand All @@ -477,11 +479,11 @@ impl Manager {
if let Some(evdev) = source_device.evdev {
configs.push(evdev);
}
if configs.len() == 0 {
if configs.is_empty() {
continue;
}
if config.has_matching_evdev(&info, &configs) {
log::info!("Found missing device, adding source device to existing composite device");
log::info!("Found missing device, adding source device {id} to existing composite device: {composite_device}");
let handle = self.composite_devices.get(composite_device.as_str());
if handle.is_none() {
log::error!(
Expand All @@ -491,6 +493,9 @@ impl Manager {
continue;
}
self.add_event_device_to_composite_device(&info, handle.unwrap())?;
self.source_devices_used
.insert(id, composite_device.clone());

return Ok(());
}
}
Expand All @@ -502,11 +507,11 @@ impl Manager {
if let Some(hidraw) = source_device.hidraw {
configs.push(hidraw);
}
if configs.len() == 0 {
if configs.is_empty() {
continue;
}
if config.has_matching_hidraw(&info, &configs) {
log::info!("Found missing device, adding source device to existing composite device");
log::info!("Found missing device, adding source device {id} to existing composite device: {composite_device}");
let handle = self.composite_devices.get(composite_device.as_str());
if handle.is_none() {
log::error!(
Expand All @@ -516,6 +521,8 @@ impl Manager {
continue;
}
self.add_hidraw_device_to_composite_device(&info, handle.unwrap())?;
self.source_devices_used
.insert(id, composite_device.clone());

return Ok(());
}
Expand Down Expand Up @@ -548,7 +555,7 @@ impl Manager {
if let Some(evdev) = source_device.evdev {
configs.push(evdev);
}
if configs.len() == 0 {
if configs.is_empty() {
continue;
}
if config.has_matching_evdev(&info, &configs) {
Expand All @@ -574,7 +581,7 @@ impl Manager {
if let Some(hidraw) = source_device.hidraw {
configs.push(hidraw);
}
if configs.len() == 0 {
if configs.is_empty() {
continue;
}
if config.has_matching_hidraw(&info, &configs) {
Expand Down Expand Up @@ -648,13 +655,14 @@ impl Manager {
.await?;

// Signal that a source device was added
self.tx.send(Command::SourceDeviceAdded(
SourceDeviceInfo::EvdevDeviceInfo(info),
))?;
let id = format!("evdev://{}", handler);
self.tx.send(Command::SourceDeviceAdded {
id: id.clone(),
info: SourceDeviceInfo::EvdevDeviceInfo(info),
})?;

// Add the device as a source device
let path = source::evdev::get_dbus_path(handler.clone());
let id = format!("evdev://{}", handler);
self.source_devices.insert(id, path);

Ok(())
Expand All @@ -667,6 +675,7 @@ impl Manager {
// Remove the device from our hashmap
let id = format!("evdev://{}", handler);
self.source_devices.remove(&id);
self.source_devices_used.remove(&id);

// Remove the DBus interface
let path = source::evdev::get_dbus_path(handler);
Expand Down Expand Up @@ -704,25 +713,30 @@ impl Manager {
source::hidraw::DBusInterface::listen_on_dbus(self.dbus.clone(), info.clone()).await?;

// Signal that a source device was added
self.tx.send(Command::SourceDeviceAdded(
SourceDeviceInfo::HIDRawDeviceInfo(info),
))?;
let id = format!("hidraw://{}", name);
self.tx.send(Command::SourceDeviceAdded {
id: id.clone(),
info: SourceDeviceInfo::HIDRawDeviceInfo(info),
})?;

// Add the device as a source device
let path = source::hidraw::get_dbus_path(path);
let id = format!("hidraw://{}", name);
self.source_devices.insert(id, path);

Ok(())
}

/// Called when a hidraw device (e.g. /dev/hidraw0) is removed
async fn on_hidraw_removed(&self, name: String) -> Result<(), Box<dyn Error>> {
async fn on_hidraw_removed(&mut self, name: String) -> Result<(), Box<dyn Error>> {
log::debug!("HIDRaw removed: {}", name);
let id = format!("hidraw://{}", name);

// Signal that a source device was removed
self.tx.send(Command::SourceDeviceRemoved { id })?;
self.tx
.send(Command::SourceDeviceRemoved { id: id.clone() })?;

self.source_devices.remove(&id);
self.source_devices_used.remove(&id);

Ok(())
}
Expand Down Expand Up @@ -885,9 +899,9 @@ impl Manager {
pub async fn load_capability_mappings(&self) -> HashMap<String, CapabilityMap> {
let mut mappings = HashMap::new();
let paths = vec![
"/usr/share/inputplumber/capability_maps",
"/etc/inputplumber/capability_maps.d",
"./rootfs/usr/share/inputplumber/capability_maps",
"/etc/inputplumber/capability_maps.d",
"/usr/share/inputplumber/capability_maps",
];

// Look for capability mappings in all known locations
Expand Down Expand Up @@ -935,13 +949,14 @@ impl Manager {
let task = tokio::task::spawn_blocking(move || {
let mut devices: Vec<CompositeDeviceConfig> = Vec::new();
let paths = vec![
"/usr/share/inputplumber/devices",
"/etc/inputplumber/devices.d",
"./rootfs/usr/share/inputplumber/devices",
"/etc/inputplumber/devices.d",
"/usr/share/inputplumber/devices",
];

// Look for composite device profiles in all known locations
for path in paths {
log::debug!("Checking {path} for composite device configs");
let files = fs::read_dir(path);
if files.is_err() {
log::debug!("Failed to load directory {}: {}", path, files.unwrap_err());
Expand Down Expand Up @@ -979,7 +994,12 @@ impl Manager {
devices
});

task.await.unwrap_or_default()
let result = task.await;
if let Err(ref e) = result {
log::error!("Failed to run task to list device configs: {:?}", e);
}

result.unwrap_or_default()
}

/// Creates a DBus object
Expand All @@ -989,6 +1009,9 @@ impl Manager {
self.dbus.object_server().at(manager_path, iface).await?;
Ok(())
}

/// Send a signal using the given composite device handle that a new source
/// device should be started.
fn add_event_device_to_composite_device(
&self,
device_info: &procfs::device::Device,
Expand All @@ -1002,6 +1025,8 @@ impl Manager {
Ok(())
}

/// Send a signal using the given composite device handle that a new source
/// device should be started.
fn add_hidraw_device_to_composite_device(
&self,
device_info: &hidapi::DeviceInfo,
Expand Down
Loading

0 comments on commit 3ec9eeb

Please sign in to comment.