Skip to content

Commit 5ba3571

Browse files
committed
fix(InputManager): Fix duplicate target creation.
- InputManager does not use the same device queue process when starting a composite device that we use for setting the target devices after it is started. If an external process connects to the dbus interface and uses set_target_devices before the InputManager has finished starting all targets it can pass all checks against de-duplication and start multiple conflicting targets. As a remedy, instead of doing a custom one off method at init, grab the ComposteDeviceClient and set the target devices the same way.
1 parent 7987798 commit 5ba3571

File tree

1 file changed

+13
-43
lines changed

1 file changed

+13
-43
lines changed

src/input/manager.rs

Lines changed: 13 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -813,14 +813,24 @@ impl Manager {
813813
.unwrap();
814814
sources.push(source_device);
815815

816-
device.listen_on_dbus().await?;
817-
818816
// Get a handle to the device
819817
let client = device.client();
820818

821819
// Keep track of target devices that this composite device is using
822820
let mut target_device_paths = Vec::new();
823821

822+
// Queue target devices based on the configuration
823+
let mut target_devices = Vec::new();
824+
if let Some(target_devices_config) = target_types {
825+
for kind in target_devices_config {
826+
let Ok(target_id) = TargetDeviceTypeId::try_from(kind.as_str()) else {
827+
return Err("Invalid target device ID".to_string().into());
828+
};
829+
target_devices.push(target_id);
830+
}
831+
}
832+
client.set_target_devices(target_devices).await?;
833+
824834
// Create a DBus target device
825835
log::debug!("Creating target devices for {composite_path}");
826836
let dbus_device = self.create_target_device("dbus").await?;
@@ -830,6 +840,7 @@ impl Manager {
830840
target_device_paths.push(dbus_path.clone());
831841
}
832842
device.set_dbus_devices(dbus_devices);
843+
device.listen_on_dbus().await?;
833844

834845
// Add the device to our maps
835846
self.composite_devices
@@ -844,7 +855,6 @@ impl Manager {
844855

845856
// Run the device
846857
let composite_path = String::from(device.dbus_path());
847-
let composite_path_clone = composite_path.clone();
848858
let tx = self.tx.clone();
849859
let task = tokio::spawn(async move {
850860
if let Err(e) = device.run().await {
@@ -864,46 +874,6 @@ impl Manager {
864874
}
865875
});
866876

867-
// Create target devices based on the configuration
868-
let mut target_devices = Vec::new();
869-
if let Some(target_devices_config) = target_types {
870-
for kind in target_devices_config {
871-
let device = self.create_target_device(kind.as_str()).await?;
872-
target_devices.push(device);
873-
}
874-
}
875-
876-
// Start the target input devices
877-
let targets = self.start_target_devices(target_devices).await?;
878-
let target_paths = targets.keys();
879-
for target_path in target_paths {
880-
target_device_paths.push(target_path.clone());
881-
}
882-
883-
// Attach the target devices
884-
let tx = self.tx.clone();
885-
tokio::task::spawn(async move {
886-
// Queue the target device attachment to the composite device
887-
for target_path in targets.into_keys() {
888-
let (sender, mut receiver) = mpsc::channel(1);
889-
let result = tx
890-
.send(ManagerCommand::AttachTargetDevice {
891-
target_path,
892-
composite_path: composite_path_clone.clone(),
893-
sender,
894-
})
895-
.await;
896-
897-
if let Err(e) = result {
898-
log::error!("Failed to send target device attach command to manager: {e:?}");
899-
continue;
900-
}
901-
tokio::task::spawn(async move {
902-
receiver.recv().await;
903-
});
904-
}
905-
});
906-
907877
Ok(task)
908878
}
909879

0 commit comments

Comments
 (0)