Skip to content

Commit

Permalink
fix(Device Hiding): revert back to previous hiding method"
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowApex committed Feb 10, 2025
1 parent d694c26 commit a439fbc
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 117 deletions.
1 change: 1 addition & 0 deletions rootfs/usr/lib/udev/hwdb.d/59-inputplumber.hwdb
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ evdev:name:AT Translated Set 2 keyboard:dmi:*:svnAYANEO:*
evdev:name:AT Translated Set 2 keyboard:dmi:*:svnOrangePi:pnNEO-01:*
KEYBOARD_KEY_66=f15
KEYBOARD_KEY_67=f16

10 changes: 5 additions & 5 deletions rootfs/usr/share/inputplumber/devices/60-horipad_steam.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ kind: CompositeDevice
# Name of the composite device mapping
name: Horipad Steam

# Only allow a CompositeDevice to manage at most the given number of
# source devices. When this limit is reached, a new CompositeDevice will be
# created for any new matching devices.
maximum_sources: 2

# Only use this profile if *any* of the given matches matches. If this list is
# empty,then the source devices will *always* be checked.
# /sys/class/dmi/id/product_name
matches: []

# Only allow a CompositeDevice to manage at most the given number of
# source devices. When this limit is reached, a new CompositeDevice will be
# created for any new matching devices.
maximum_sources: 2

# One or more source devices to combine into a single virtual device. The events
# from these devices will be watched and translated according to the key map.
source_devices:
Expand Down
37 changes: 37 additions & 0 deletions rootfs/usr/share/inputplumber/devices/69-ignore_generic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/ShadowBlip/InputPlumber/main/rootfs/usr/share/inputplumber/schema/composite_device_v1.json
# Schema version number
version: 1

# The type of configuration schema
kind: CompositeDevice

# Name of the composite device mapping
name: Ignore Gamepads

# Maximum number of source devices per CompositeDevice.
maximum_sources: 1

# Only use this profile if *any* of the given matches matches. If this list is
# empty, then the source devices will *always* be checked.
# /sys/class/dmi/id/product_name
matches: []

# One or more source devices to combine into a single virtual device. The events
# from these devices will be watched and translated according to the key map.
source_devices:
- group: gamepad
ignore: true
evdev:
handler: js*
- group: gamepad
ignore: true
evdev:
handler: event*
- group: mouse
ignore: true
evdev:
handler: mouse*
- group: mouse
ignore: true
evdev:
handler: mice*
30 changes: 0 additions & 30 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,6 @@ pub enum Commands {
#[command(subcommand)]
cmd: TargetsCommand,
},
/// Query input devices
Query {
/// Sysfs path to the device to query
sysfs_path: String,
#[arg(long, action)]
subsystem: Option<String>,
#[arg(long, action)]
udev: Option<bool>,
},
}

pub async fn main_cli(args: Args) -> Result<(), Box<dyn Error>> {
Expand All @@ -74,27 +65,6 @@ pub async fn main_cli(args: Args) -> Result<(), Box<dyn Error>> {
Commands::Device { id: number, cmd } => handle_device(connection, cmd, number).await?,
Commands::Devices { cmd } => handle_devices(connection, cmd).await?,
Commands::Targets { cmd } => handle_targets(connection, cmd).await?,
Commands::Query {
udev,
sysfs_path,
subsystem,
} => {
// example:
// inputplumber query /devices/pci0000:00/0000:00:08.3/0000:c3:00.4/usb7/7-1/7-1:1.0/input/input83/event11

// Check to see if the device is virtual
let is_virtual =
sysfs_path.contains("devices/virtual") || sysfs_path.contains("vhci_hcd");

if !is_virtual {
return Ok(());
}

// Bluetooth devices are virtual, so ensure ensure the device is not bluetooth

//println!("Found option: {udev:?}");
println!("INPUTPLUMBER_VIRT=1")
}
}

Ok(())
Expand Down
13 changes: 1 addition & 12 deletions src/input/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ use crate::input::source::iio;
use crate::input::target::TargetDevice;
use crate::input::target::TargetDeviceTypeId;
use crate::udev;
use crate::udev::block_joysticks;
use crate::udev::device::AttributeGetter;
use crate::udev::device::UdevDevice;
use crate::udev::unblock_joysticks;

use super::composite_device::client::CompositeDeviceClient;
use super::target::client::TargetDeviceClient;
Expand Down Expand Up @@ -352,13 +350,8 @@ impl Manager {
}
self.manage_all_devices = manage_all_devices;

// If management of all devices was enabled, add the needed udev rules and trigger
// device discovery
// If management of all devices was enabled, trigger device discovery
if manage_all_devices {
if let Err(e) = block_joysticks().await {
log::error!("Failed to set udev rules to block source devices. Double input is possible. {e:?}");
}

let cmd_tx = self.tx.clone();
tokio::task::spawn(async move {
if let Err(e) = Manager::discover_all_devices(&cmd_tx).await {
Expand All @@ -370,10 +363,6 @@ impl Manager {

// If management was disabled, stop any composite devices that
// are not auto-managed.
if let Err(e) = unblock_joysticks().await {
log::error!("Failed to unset udev rules blocking source devices. Input devices may be unavailable. {e:?}");
}

for (dbus_path, config) in self.used_configs.iter() {
if let Some(options) = config.options.as_ref() {
let auto_managed = options.auto_manage.unwrap_or(false);
Expand Down
2 changes: 1 addition & 1 deletion src/input/target/xb360.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl XBox360Controller {
ff.insert(FFEffectCode::FF_GAIN);

// Identify to the kernel as an Xbox One Elite
let id = InputId::new(BusType(3), 0x045e, 0x028e, 0xaced);
let id = InputId::new(BusType(3), 0x045e, 0x028e, 0x0001);

// Build the device
let device = VirtualDeviceBuilder::new()?
Expand Down
2 changes: 1 addition & 1 deletion src/input/target/xbox_elite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl XboxEliteController {
ff.insert(FFEffectCode::FF_GAIN);

// Identify to the kernel as an Xbox One Elite
let id = InputId::new(BusType(3), 0x045e, 0x0b00, 0xaced);
let id = InputId::new(BusType(3), 0x045e, 0x0b00, 0x0001);

// Build the device
let device = VirtualDeviceBuilder::new()?
Expand Down
2 changes: 1 addition & 1 deletion src/input/target/xbox_series.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl XboxSeriesController {
ff.insert(FFEffectCode::FF_GAIN);

// Identify to the kernel as an Xbox One Elite
let id = InputId::new(BusType(3), 0x045e, 0x0b12, 0xaced);
let id = InputId::new(BusType(3), 0x045e, 0x0b12, 0x0001);

// Build the device
let device = VirtualDeviceBuilder::new()?
Expand Down
4 changes: 0 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use clap::Parser;
use inputplumber::udev::unblock_joysticks;
use std::env;
use std::error::Error;
use std::process;
Expand Down Expand Up @@ -63,9 +62,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
tokio::spawn(async move {
tokio::signal::ctrl_c().await.unwrap();
log::info!("Un-hiding all devices");
if let Err(e) = unblock_joysticks().await {
log::error!("Unable to unblock normal joysticks: {e:?}");
}
if let Err(e) = unhide_all().await {
log::error!("Unable to un-hide devices: {:?}", e);
}
Expand Down
70 changes: 7 additions & 63 deletions src/udev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,68 +13,9 @@ use udev::Enumerator;

use self::device::Device;

const RULE_PRIORITY: &str = "59";
const RULE_HIDE_DEVICE_PRIORITY: &str = "50";
const RULES_PREFIX: &str = "/run/udev/rules.d";

/// Hide all removable input devices from regular users.
pub async fn block_joysticks() -> Result<(), Box<dyn Error>> {
// Find the chmod command to use for hiding
let chmod_cmd = if Path::new("/bin/chmod").exists() {
"/bin/chmod"
} else {
"/usr/bin/chmod"
};

const IP_CMD: &str = "/home/william/Projects/InputPlumber/target/debug/inputplumber";

let rule = format!(
r#"# InputPlumber device hiding rules
# Managed by InputPlumber, this file will be autoremoved during configuration changes.
# Query InputPlumber to see if the given device is being managed by InputPlumber.
# If it is, add the INPUTPLUMBER_VIRT property to the device.
ACTION=="add|change", KERNEL=="hidraw[0-9]*|js[0-9]*|event[0-9]*", IMPORT{{program}}="{IP_CMD} query %p"
# Create symlinks for all virtual InputPlumber devices
ACTION=="add|change", KERNEL=="hidraw[0-9]*|js[0-9]*|event[0-9]*", ENV{{INPUTPLUMBER_VIRT}}=="1", SYMLINK+="inputplumber/by-targets/%k", GOTO="inputplumber_end"
# Hide all evdev gamepads that are not InputPlumber virtual devices
ACTION=="add|change", KERNEL=="js[0-9]*|event[0-9]*", ENV{{ID_INPUT_JOYSTICK}}=="1", ENV{{INPUTPLUMBER_VIRT}}!="1", SYMLINK+="inputplumber/by-hidden/%k", MODE:="0000", GROUP:="root", RUN:="{chmod_cmd} 000 %p"
# Hide all Horipad Steam Controller hidraw devices
ACTION=="add|change", SUBSYSTEM=="hidraw", KERNEL=="hidraw[0-9]*", ATTR{{idVendor}}=="0F0D", ATTR{{idProduct}}=="0196", ENV{{INPUTPLUMBER_VIRT}}!="1", SYMLINK+="inputplumber/by-hidden/%k", MODE:="0000", GROUP:="root", RUN:="{chmod_cmd} 000 %p"
ACTION=="add|change", SUBSYSTEM=="hidraw", KERNEL=="hidraw[0-9]*", ATTR{{idVendor}}=="0F0D", ATTR{{idProduct}}=="01AB", ENV{{INPUTPLUMBER_VIRT}}!="1", SYMLINK+="inputplumber/by-hidden/%k", MODE:="0000", GROUP:="root", RUN:="{chmod_cmd} 000 %p"
# Hide all PlayStation hidraw devices
ACTION=="add|change", SUBSYSTEMS=="hid", DRIVERS=="playstation", GOTO="playstation_start"
GOTO="playstation_end"
LABEL="playstation_start"
ACTION=="add|change", SUBSYSTEM=="hidraw", KERNEL=="hidraw[0-9]*", ENV{{INPUTPLUMBER_VIRT}}!="1", SYMLINK+="inputplumber/by-hidden/%k", MODE:="0000", GROUP:="root", RUN:="{chmod_cmd} 000 %p"
LABEL="playstation_end"
LABEL="inputplumber_end"
"#
);

// Write the udev rule
fs::create_dir_all(RULES_PREFIX)?;
let rule_path = format!("{RULES_PREFIX}/51-inputplumber-hide-joysticks.rules");
fs::write(rule_path, rule)?;

reload_all().await?;

Ok(())
}

/// Unhide all removable input devices from regular users.
pub async fn unblock_joysticks() -> Result<(), Box<dyn Error>> {
let rule_path = format!("{RULES_PREFIX}/51-inputplumber-hide-joysticks.rules");
fs::remove_file(rule_path)?;
reload_all().await?;

Ok(())
}

/// Hide the given input device from regular users.
pub async fn hide_device(path: &str) -> Result<(), Box<dyn Error>> {
// Get the device to hide
Expand Down Expand Up @@ -109,7 +50,8 @@ LABEL="inputplumber_end"

// Write the udev rule
fs::create_dir_all(RULES_PREFIX)?;
let rule_path = format!("{RULES_PREFIX}/{RULE_PRIORITY}-inputplumber-hide-{name}.rules");
let rule_path =
format!("{RULES_PREFIX}/{RULE_HIDE_DEVICE_PRIORITY}-inputplumber-hide-{name}.rules");
fs::write(rule_path, rule)?;

// Reload udev
Expand All @@ -126,7 +68,8 @@ pub async fn unhide_device(path: String) -> Result<(), Box<dyn Error>> {
let Some(parent) = device.get_parent() else {
return Err("Unable to determine parent for device".into());
};
let rule_path = format!("{RULES_PREFIX}/{RULE_PRIORITY}-inputplumber-hide-{name}.rules");
let rule_path =
format!("{RULES_PREFIX}/{RULE_HIDE_DEVICE_PRIORITY}-inputplumber-hide-{name}.rules");
fs::remove_file(rule_path)?;

// Reload udev
Expand All @@ -143,7 +86,8 @@ pub async fn unhide_all() -> Result<(), Box<dyn Error>> {
continue;
};
let filename = entry.file_name().to_string_lossy().to_string();
if !filename.starts_with(format!("{RULE_PRIORITY}-inputplumber-hide").as_str()) {
if !filename.starts_with(format!("{RULE_HIDE_DEVICE_PRIORITY}-inputplumber-hide").as_str())
{
continue;
}
let path = entry.path().to_string_lossy().to_string();
Expand Down

0 comments on commit a439fbc

Please sign in to comment.