Skip to content

Commit

Permalink
fix(CompositeDevice): move device hiding logic back to device start i…
Browse files Browse the repository at this point in the history
…nstead of device add
  • Loading branch information
ShadowApex committed Feb 13, 2025
1 parent 3e01cb1 commit ac5f7e0
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
1 change: 1 addition & 0 deletions rootfs/usr/lib/systemd/system/inputplumber.service
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Description=InputPlumber Service

[Service]
Environment=LOG_LEVEL=info
ExecStart=/usr/bin/inputplumber

[Install]
Expand Down
25 changes: 16 additions & 9 deletions src/input/composite_device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ pub struct CompositeDevice {
source_devices: HashMap<String, SourceDeviceClient>,
/// Source devices that this composite device will consume.
source_devices_discovered: Vec<SourceDevice>,
/// Source devices that should be hidden before they are started. This
/// is a list of devnode paths to hide (e.g. ["/dev/input/event10", "/dev/hidraw1"])
source_devices_to_hide: Vec<String>,
/// HashSet of source devices that are blocked from passing their input events to target
/// events.
source_devices_blocked: HashSet<String>,
Expand Down Expand Up @@ -165,7 +168,7 @@ pub struct CompositeDevice {
}

impl CompositeDevice {
pub async fn new(
pub fn new(
conn: Connection,
manager: mpsc::Sender<ManagerCommand>,
config: CompositeDeviceConfig,
Expand Down Expand Up @@ -195,6 +198,7 @@ impl CompositeDevice {
rx,
source_devices: HashMap::new(),
source_devices_discovered: Vec::new(),
source_devices_to_hide: Vec::new(),
source_devices_blocked: HashSet::new(),
source_device_paths: Vec::new(),
source_device_tasks: JoinSet::new(),
Expand Down Expand Up @@ -239,7 +243,7 @@ impl CompositeDevice {
}
}

if let Err(e) = device.add_source_device(device_info).await {
if let Err(e) = device.add_source_device(device_info) {
return Err(e.to_string().into());
}

Expand Down Expand Up @@ -602,7 +606,13 @@ impl CompositeDevice {
/// Start and run the source devices that this composite device will
/// consume.
async fn run_source_devices(&mut self) -> Result<(), Box<dyn Error>> {
// Keep a list of all the tasks
// Hide the device if specified
for source_path in self.source_devices_to_hide.drain(..) {
log::debug!("Hiding device: {}", source_path);
if let Err(e) = hide_device(source_path.as_str()).await {
log::warn!("Failed to hide device '{source_path}': {e:?}");
}
}

log::debug!("Starting new source devices");
// Start listening for events from all source devices
Expand Down Expand Up @@ -1387,7 +1397,7 @@ impl CompositeDevice {

/// Executed whenever a source device is added to this [CompositeDevice].
async fn on_source_device_added(&mut self, device: UdevDevice) -> Result<(), Box<dyn Error>> {
if let Err(e) = self.add_source_device(device).await {
if let Err(e) = self.add_source_device(device) {
return Err(e.to_string().into());
}
self.run_source_devices().await?;
Expand Down Expand Up @@ -1432,7 +1442,7 @@ impl CompositeDevice {
}

/// Creates and adds a source device using the given [SourceDeviceInfo]
async fn add_source_device(
fn add_source_device(
&mut self,
device: UdevDevice,
) -> Result<(), Box<dyn Error + Send + Sync>> {
Expand All @@ -1456,10 +1466,7 @@ impl CompositeDevice {
let should_hide = !should_passthru && subsystem.as_str() != "iio";
if should_hide {
let source_path = device.devnode();
log::debug!("Hiding device: {}", source_path);
if let Err(e) = hide_device(source_path.as_str()).await {
log::warn!("Failed to hide device '{source_path}': {e:?}");
}
self.source_devices_to_hide.push(source_path);
}

let source_device = match subsystem.as_str() {
Expand Down
15 changes: 13 additions & 2 deletions src/input/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::HashMap;
use std::collections::HashSet;
use std::error::Error;
use std::fs;
use std::path::PathBuf;
use std::time::Duration;

use ::procfs::CpuInfo;
Expand Down Expand Up @@ -210,6 +211,10 @@ impl Manager {
/// Starts listening for [Command] messages to be sent from clients and
/// dispatch those events.
pub async fn run(&mut self) -> Result<(), Box<dyn Error + Send + Sync>> {
// Delay initial discovery by a short amount of time to allow udev
// rules to process for the first time.
tokio::time::sleep(Duration::from_millis(1000)).await;

let dbus_for_listen_on_dbus = self.dbus.clone();

let cmd_tx_all_devices = self.tx.clone();
Expand Down Expand Up @@ -546,8 +551,7 @@ impl Manager {
device,
self.next_composite_dbus_path()?,
capability_map,
)
.await?;
)?;

// Check to see if there's already a CompositeDevice for
// these source devices.
Expand Down Expand Up @@ -1553,6 +1557,13 @@ impl Manager {
continue;
};

// Ensure the path is a valid devnode
let full_path = PathBuf::from(format!("{base_path}/{name}"));
if full_path.is_dir() {
log::trace!("Devnode path {base_path}/{name} is a directory. Skipping.");
continue;
}

// Wait until the device has initialized with udev
const MAX_TRIES: u8 = 80;
let mut attempt: u8 = 0;
Expand Down
6 changes: 5 additions & 1 deletion src/udev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub async fn hide_device(path: &str) -> Result<(), Box<dyn Error>> {
{match_rule}, GOTO="inputplumber_valid"
GOTO="inputplumber_end"
LABEL="inputplumber_valid"
ACTION=="add|change", KERNEL=="hidraw[0-9]*|js[0-9]*|event[0-9]*", SUBSYSTEM=="{subsystem}", MODE:="0000", GROUP:="root", RUN:="{chmod_cmd} 000 {path}", SYMLINK+="inputplumber/by-hidden/%k"
KERNEL=="hidraw[0-9]*|js[0-9]*|event[0-9]*", SUBSYSTEM=="{subsystem}", MODE="000", GROUP="root", RUN:="{chmod_cmd} 000 {path}", SYMLINK+="inputplumber/by-hidden/%k"
LABEL="inputplumber_end"
"#
);
Expand Down Expand Up @@ -102,12 +102,14 @@ pub async fn unhide_all() -> Result<(), Box<dyn Error>> {

/// Trigger udev to evaluate rules on the children of the given parent device path
async fn reload_children(parent: String) -> Result<(), Box<dyn Error>> {
log::debug!("Reloading udev rules: udevadm control --reload-rules");
let _ = Command::new("udevadm")
.args(["control", "--reload-rules"])
.output()
.await?;

for action in ["remove", "add"] {
log::debug!("Retriggering udev rules: udevadm trigger --action {action} -b {parent}");
let _ = Command::new("udevadm")
.args(["trigger", "--action", action, "-b", parent.as_str()])
.output()
Expand All @@ -119,11 +121,13 @@ async fn reload_children(parent: String) -> Result<(), Box<dyn Error>> {

/// Trigger udev to evaluate rules on the children of the given parent device path
async fn reload_all() -> Result<(), Box<dyn Error>> {
log::debug!("Reloading udev rules: udevadm control --reload-rules");
let _ = Command::new("udevadm")
.args(["control", "--reload-rules"])
.output()
.await?;

log::debug!("Retriggering udev rules: udevadm trigger");
let _ = Command::new("udevadm").arg("trigger").output().await?;

Ok(())
Expand Down

0 comments on commit ac5f7e0

Please sign in to comment.