fix(bluetooth): other devices not initially appearing

This commit is contained in:
Michael Aaron Murphy 2025-04-17 17:30:19 +02:00
parent e7f24828f1
commit 4f1ef57fe2
No known key found for this signature in database
GPG key ID: B2732D4240C9212C

View file

@ -27,8 +27,8 @@ use tokio::{
Mutex, Mutex,
}, },
task::JoinHandle, task::JoinHandle,
time::timeout,
}; };
// Copied from https://github.com/bluez/bluez/blob/39467578207889fd015775cbe81a3db9dd26abea/src/dbus-common.c#L53 // Copied from https://github.com/bluez/bluez/blob/39467578207889fd015775cbe81a3db9dd26abea/src/dbus-common.c#L53
#[inline] #[inline]
fn device_type_to_icon(device_type: &str) -> &'static str { fn device_type_to_icon(device_type: &str) -> &'static str {
@ -299,7 +299,6 @@ pub enum BluerSessionEvent {
err_msg: Option<String>, err_msg: Option<String>,
}, },
ChangesProcessed(BluerState), ChangesProcessed(BluerState),
ChangeStreamEnded, // TODO can we just restart the stream in a new task?
AgentEvent(BluerAgentEvent), AgentEvent(BluerAgentEvent),
} }
@ -567,45 +566,27 @@ impl BluerSessionState {
return; return;
}; };
let adapter_clone = self.adapter.clone(); let adapter_clone = self.adapter.clone();
let _monitor_devices: tokio::task::JoinHandle<Result<(), anyhow::Error>> = spawn( let _monitor_devices: tokio::task::JoinHandle<Result<(), anyhow::Error>> =
async move { spawn(async move {
let mut change_stream = { let mut devices: Vec<BluerDevice> = Vec::new();
let mut milli_timeout = 10;
let mut res = adapter_clone.discover_devices_with_changes().await;
while res.is_err() {
_ = tokio::time::timeout(
Duration::from_millis(milli_timeout),
wake_up.recv(),
)
.await;
res = adapter_clone.discover_devices_with_changes().await;
milli_timeout = milli_timeout.saturating_mul(5);
}
res.unwrap()
};
let mut interval = tokio::time::interval(Duration::from_secs(1));
loop { loop {
let mut milli_timeout = 10; let wakeup_fut = wake_up.recv();
let mut devices: Vec<BluerDevice> = Vec::new();
// Listens for process changes and builds edvice lists.
let listener_fut = async {
let mut new_devices = Vec::new(); let mut new_devices = Vec::new();
'outer: loop { let mut interval = tokio::time::interval(Duration::from_secs(1));
tokio::select! { let mut change_stream =
change = timeout(Duration::from_millis(milli_timeout), change_stream.next()) => { match adapter_clone.discover_devices_with_changes().await {
if let Ok(e) = change { Ok(stream) => stream,
if e.is_none() { Err(_) => {
break 'outer; interval.tick().await;
} return;
} else {
milli_timeout = milli_timeout.saturating_mul(2);
continue;
}
}
_wake = wake_up.recv() => {
} }
}; };
while let Some(_) = change_stream.next().await {
new_devices = build_device_list(new_devices, &adapter_clone).await; new_devices = build_device_list(new_devices, &adapter_clone).await;
for d in new_devices for d in new_devices
.iter() .iter()
@ -614,22 +595,28 @@ impl BluerSessionState {
_ = req_tx.send(BluerRequest::ConnectDevice(d.address)).await; _ = req_tx.send(BluerRequest::ConnectDevice(d.address)).await;
} }
mem::swap(&mut new_devices, &mut devices);
let _ = tx let _ = tx
.send(BluerSessionEvent::ChangesProcessed(BluerState { .send(BluerSessionEvent::ChangesProcessed(BluerState {
devices: devices.clone(), devices: new_devices.clone(),
bluetooth_enabled: adapter_clone bluetooth_enabled: adapter_clone
.is_powered() .is_powered()
.await .await
.unwrap_or_default(), .unwrap_or_default(),
})) }))
.await; .await;
devices.clear();
mem::swap(&mut new_devices, &mut devices);
interval.tick().await; interval.tick().await;
} }
let _ = tx.send(BluerSessionEvent::ChangeStreamEnded).await; };
futures::pin_mut!(listener_fut);
futures::pin_mut!(wakeup_fut);
futures::future::select(listener_fut, wakeup_fut).await;
} }
}, });
);
} }
#[inline] #[inline]