diff --git a/credentialsd/src/dbus/ui_control.rs b/credentialsd/src/dbus/ui_control.rs index 921ef61..70899e2 100644 --- a/credentialsd/src/dbus/ui_control.rs +++ b/credentialsd/src/dbus/ui_control.rs @@ -467,12 +467,22 @@ impl UiController for UiControlServiceClient { }; subscribe_ui_events( self.conn.clone(), - sender, + sender.clone(), session_handle.clone(), - from_ui_tx, + from_ui_tx.clone(), ) .await?; + // We want to know when this specific peer disconnects + let peer = zbus::proxy::Builder::::new(&self.conn) + .destination(sender)? + .path(backend_proxy.as_ref().path())? + .interface(backend_proxy.as_ref().interface())? + .build() + .await?; + let owner_changes = peer.receive_owner_changed().await?; + watch_ui_exit(owner_changes, session_handle.clone(), from_ui_tx); + backend_proxy .create_session( session_handle.as_ref(), @@ -494,6 +504,28 @@ impl UiController for UiControlServiceClient { } } +fn watch_ui_exit( + owner_changes: proxy::OwnerChangedStream<'static>, + session_handle: OwnedObjectPath, + tx: mpsc::Sender, +) { + tokio::spawn(async move { + let mut owner_changes = Box::pin(owner_changes); + while let Some(owner) = tokio::select! { + // Nothing is listening for ceremony events any more + _ = tx.closed() => None, + owner = owner_changes.next() => owner, + } { + // A well-known name yields `None` once it is released. + if owner.is_none() { + tracing::debug!(session_handle = %session_handle, "UI left the bus, cancelling request"); + _ = tx.send(UserInteractedEvent::RequestCancelled).await; + return; + } + } + }); +} + async fn subscribe_ui_events( connection: Connection, sender: OwnedUniqueName,