|
1 | 1 | use std::{collections::HashMap, sync::RwLock};
|
2 | 2 |
|
3 |
| -use zbus::zvariant::{ObjectPath, OwnedObjectPath}; |
| 3 | +use futures_util::stream::StreamExt; |
| 4 | +use zbus::{ |
| 5 | + zvariant::{ObjectPath, OwnedObjectPath}, |
| 6 | + Connection, MatchRule, MessageStream, |
| 7 | +}; |
4 | 8 |
|
5 | 9 | use super::{collection::Collection, session::Session};
|
| 10 | +use crate::daemon; |
6 | 11 |
|
7 | 12 | #[derive(Debug, Default)]
|
8 | 13 | pub struct ServiceManager {
|
9 | 14 | sessions: HashMap<OwnedObjectPath, Session>,
|
10 | 15 | collections: HashMap<String, Collection>,
|
11 | 16 | collections_to_unlock: Vec<OwnedObjectPath>,
|
| 17 | + peers: HashMap<String, OwnedObjectPath>, |
12 | 18 | unlock_request_sender: RwLock<String>,
|
13 | 19 | unlock_prompt_path: RwLock<OwnedObjectPath>,
|
14 | 20 | prompts_counter: RwLock<i32>,
|
@@ -70,6 +76,18 @@ impl ServiceManager {
|
70 | 76 | *self.unlock_prompt_path.write().unwrap() = path.into();
|
71 | 77 | }
|
72 | 78 |
|
| 79 | + pub fn peer(&self, peer: String) -> Option<OwnedObjectPath> { |
| 80 | + self.peers.get(&peer).cloned() |
| 81 | + } |
| 82 | + |
| 83 | + pub fn insert_peer(&mut self, peer: String, path: ObjectPath<'_>) { |
| 84 | + self.peers.insert(peer, path.into()); |
| 85 | + } |
| 86 | + |
| 87 | + pub fn remove_peer(&mut self, peer: String) { |
| 88 | + self.peers.remove(&peer); |
| 89 | + } |
| 90 | + |
73 | 91 | pub fn prompts_counter(&self) -> i32 {
|
74 | 92 | *self.prompts_counter.read().unwrap()
|
75 | 93 | }
|
@@ -102,4 +120,37 @@ impl ServiceManager {
|
102 | 120 | pub fn set_prompt_dismissed(&mut self, dismissed: bool) {
|
103 | 121 | self.prompt_dismissed = dismissed;
|
104 | 122 | }
|
| 123 | + |
| 124 | + pub async fn watch_peer_connections(connection: &Connection) -> daemon::Result<()> { |
| 125 | + // monitor client disconnects |
| 126 | + |
| 127 | + let rule = MatchRule::builder() |
| 128 | + .msg_type(zbus::message::Type::Signal) |
| 129 | + .sender("org.freedesktop.DBus")? |
| 130 | + .interface("org.freedesktop.DBus")? |
| 131 | + .member("NameOwnerChanged")? |
| 132 | + .add_arg("org.gnome.seahorse.Application")? |
| 133 | + .build(); |
| 134 | + |
| 135 | + let mut stream = MessageStream::for_match_rule(rule, connection, Some(1)).await?; |
| 136 | + |
| 137 | + while let Some(Ok(message)) = stream.next().await { |
| 138 | + let Ok((_, old_owner, new_owner)) = |
| 139 | + message.body().deserialize::<(String, String, String)>() |
| 140 | + else { |
| 141 | + continue; |
| 142 | + }; |
| 143 | + if new_owner == "" { |
| 144 | + // a peer is disconnecting, remove session info |
| 145 | + // https://github.com/GNOME/gnome-keyring/blob/4132075144c7bb21b897570dd53b005ac38250aa/daemon/dbus/gkd-secret-service.c#L936 |
| 146 | + tracing::info!("A peer is disconnected."); |
| 147 | + // todo: clean up |
| 148 | + println!("------------------ {old_owner}"); |
| 149 | + } else { |
| 150 | + tracing::info!("A peer connected."); |
| 151 | + } |
| 152 | + } |
| 153 | + |
| 154 | + Ok(()) |
| 155 | + } |
105 | 156 | }
|
0 commit comments