1use event_listener::{Event, EventListener};
2use serde::Serialize;
3use std::{
4 collections::{hash_map::Entry, HashMap},
5 convert::TryInto,
6 fmt::Write,
7 marker::PhantomData,
8 ops::{Deref, DerefMut},
9 sync::Arc,
10};
11use tracing::{debug, instrument, trace};
12
13use static_assertions::assert_impl_all;
14use zbus_names::InterfaceName;
15use zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Signature, Type, Value};
16
17use crate::{
18 async_lock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
19 fdo,
20 fdo::{Introspectable, ManagedObjects, ObjectManager, Peer, Properties},
21 Connection, DispatchResult, Error, Interface, Message, Result, SignalContext, WeakConnection,
22};
23
24pub struct InterfaceDeref<'d, I> {
26 iface: RwLockReadGuard<'d, dyn Interface>,
27 phantom: PhantomData<I>,
28}
29
30impl<I> Deref for InterfaceDeref<'_, I>
31where
32 I: Interface,
33{
34 type Target = I;
35
36 fn deref(&self) -> &I {
37 self.iface.downcast_ref::<I>().unwrap()
38 }
39}
40
41pub struct InterfaceDerefMut<'d, I> {
43 iface: RwLockWriteGuard<'d, dyn Interface>,
44 phantom: PhantomData<I>,
45}
46
47impl<I> Deref for InterfaceDerefMut<'_, I>
48where
49 I: Interface,
50{
51 type Target = I;
52
53 fn deref(&self) -> &I {
54 self.iface.downcast_ref::<I>().unwrap()
55 }
56}
57
58impl<I> DerefMut for InterfaceDerefMut<'_, I>
59where
60 I: Interface,
61{
62 fn deref_mut(&mut self) -> &mut Self::Target {
63 self.iface.downcast_mut::<I>().unwrap()
64 }
65}
66
67pub struct InterfaceRef<I> {
71 ctxt: SignalContext<'static>,
72 lock: Arc<RwLock<dyn Interface>>,
73 phantom: PhantomData<I>,
74}
75
76impl<I> InterfaceRef<I>
77where
78 I: 'static,
79{
80 pub async fn get(&self) -> InterfaceDeref<'_, I> {
87 let iface = self.lock.read().await;
88
89 iface
90 .downcast_ref::<I>()
91 .expect("Unexpected interface type");
92
93 InterfaceDeref {
94 iface,
95 phantom: PhantomData,
96 }
97 }
98
99 pub async fn get_mut(&self) -> InterfaceDerefMut<'_, I> {
144 let mut iface = self.lock.write().await;
145
146 iface
147 .downcast_ref::<I>()
148 .expect("Unexpected interface type");
149 iface
150 .downcast_mut::<I>()
151 .expect("Unexpected interface type");
152
153 InterfaceDerefMut {
154 iface,
155 phantom: PhantomData,
156 }
157 }
158
159 pub fn signal_context(&self) -> &SignalContext<'static> {
160 &self.ctxt
161 }
162}
163
164impl<I> Clone for InterfaceRef<I> {
165 fn clone(&self) -> Self {
166 Self {
167 ctxt: self.ctxt.clone(),
168 lock: self.lock.clone(),
169 phantom: PhantomData,
170 }
171 }
172}
173
174#[derive(Default, derivative::Derivative)]
175#[derivative(Debug)]
176pub(crate) struct Node {
177 path: OwnedObjectPath,
178 children: HashMap<String, Node>,
179 #[derivative(Debug = "ignore")]
180 interfaces: HashMap<InterfaceName<'static>, Arc<RwLock<dyn Interface>>>,
181}
182
183impl Node {
184 pub(crate) fn new(path: OwnedObjectPath) -> Self {
185 let mut node = Self {
186 path,
187 ..Default::default()
188 };
189 node.at(Peer::name(), || Arc::new(RwLock::new(Peer)));
190 node.at(Introspectable::name(), || {
191 Arc::new(RwLock::new(Introspectable))
192 });
193 node.at(Properties::name(), || Arc::new(RwLock::new(Properties)));
194
195 node
196 }
197
198 pub(crate) fn get_child(&self, path: &ObjectPath<'_>) -> Option<&Node> {
200 let mut node = self;
201
202 for i in path.split('/').skip(1) {
203 if i.is_empty() {
204 continue;
205 }
206 match node.children.get(i) {
207 Some(n) => node = n,
208 None => return None,
209 }
210 }
211
212 Some(node)
213 }
214
215 fn get_child_mut(
219 &mut self,
220 path: &ObjectPath<'_>,
221 create: bool,
222 ) -> (Option<&mut Node>, Option<ObjectPath<'_>>) {
223 let mut node = self;
224 let mut node_path = String::new();
225 let mut obj_manager_path = None;
226
227 for i in path.split('/').skip(1) {
228 if i.is_empty() {
229 continue;
230 }
231
232 if node.interfaces.contains_key(&ObjectManager::name()) {
233 obj_manager_path = Some((*node.path).clone());
234 }
235
236 write!(&mut node_path, "/{i}").unwrap();
237 match node.children.entry(i.into()) {
238 Entry::Vacant(e) => {
239 if create {
240 let path = node_path.as_str().try_into().expect("Invalid Object Path");
241 node = e.insert(Node::new(path));
242 } else {
243 return (None, obj_manager_path);
244 }
245 }
246 Entry::Occupied(e) => node = e.into_mut(),
247 }
248 }
249
250 (Some(node), obj_manager_path)
251 }
252
253 pub(crate) fn interface_lock(
254 &self,
255 interface_name: InterfaceName<'_>,
256 ) -> Option<Arc<RwLock<dyn Interface>>> {
257 self.interfaces.get(&interface_name).cloned()
258 }
259
260 fn remove_interface(&mut self, interface_name: InterfaceName<'static>) -> bool {
261 self.interfaces.remove(&interface_name).is_some()
262 }
263
264 fn is_empty(&self) -> bool {
265 !self.interfaces.keys().any(|k| {
266 *k != Peer::name()
267 && *k != Introspectable::name()
268 && *k != Properties::name()
269 && *k != ObjectManager::name()
270 })
271 }
272
273 fn remove_node(&mut self, node: &str) -> bool {
274 self.children.remove(node).is_some()
275 }
276
277 fn at<F>(&mut self, name: InterfaceName<'static>, iface_creator: F) -> bool
280 where
281 F: FnOnce() -> Arc<RwLock<dyn Interface>>,
282 {
283 match self.interfaces.entry(name) {
284 Entry::Vacant(e) => e.insert(iface_creator()),
285 Entry::Occupied(_) => return false,
286 };
287
288 true
289 }
290
291 #[async_recursion::async_recursion]
292 async fn introspect_to_writer<W: Write + Send>(&self, writer: &mut W, level: usize) {
293 if level == 0 {
294 writeln!(
295 writer,
296 r#"
297<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
298 "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
299<node>"#
300 )
301 .unwrap();
302 }
303
304 for iface in self.interfaces.values() {
305 iface.read().await.introspect_to_writer(writer, level + 2);
306 }
307
308 for (path, node) in &self.children {
309 let level = level + 2;
310 writeln!(
311 writer,
312 "{:indent$}<node name=\"{}\">",
313 "",
314 path,
315 indent = level
316 )
317 .unwrap();
318 node.introspect_to_writer(writer, level).await;
319 writeln!(writer, "{:indent$}</node>", "", indent = level).unwrap();
320 }
321
322 if level == 0 {
323 writeln!(writer, "</node>").unwrap();
324 }
325 }
326
327 pub(crate) async fn introspect(&self) -> String {
328 let mut xml = String::with_capacity(1024);
329
330 self.introspect_to_writer(&mut xml, 0).await;
331
332 xml
333 }
334
335 #[async_recursion::async_recursion]
336 pub(crate) async fn get_managed_objects(&self) -> ManagedObjects {
337 let mut managed_objects = ManagedObjects::new();
339 for node in self.children.values() {
340 let mut interfaces = HashMap::new();
341 for iface_name in node.interfaces.keys().filter(|n| {
342 *n != &Peer::name()
344 && *n != &Introspectable::name()
345 && *n != &Properties::name()
346 && *n != &ObjectManager::name()
347 }) {
348 let props = node.get_properties(iface_name.clone()).await;
349 interfaces.insert(iface_name.clone().into(), props);
350 }
351 managed_objects.insert(node.path.clone(), interfaces);
352 managed_objects.extend(node.get_managed_objects().await);
353 }
354
355 managed_objects
356 }
357
358 async fn get_properties(
359 &self,
360 interface_name: InterfaceName<'_>,
361 ) -> HashMap<String, OwnedValue> {
362 self.interface_lock(interface_name)
363 .expect("Interface was added but not found")
364 .read()
365 .await
366 .get_all()
367 .await
368 }
369}
370
371#[derive(Debug)]
429pub struct ObjectServer {
430 conn: WeakConnection,
431 root: RwLock<Node>,
432}
433
434assert_impl_all!(ObjectServer: Send, Sync, Unpin);
435
436impl ObjectServer {
437 pub(crate) fn new(conn: &Connection) -> Self {
439 Self {
440 conn: conn.into(),
441 root: RwLock::new(Node::new("/".try_into().expect("zvariant bug"))),
442 }
443 }
444
445 pub(crate) fn root(&self) -> &RwLock<Node> {
446 &self.root
447 }
448
449 pub async fn at<'p, P, I>(&self, path: P, iface: I) -> Result<bool>
458 where
459 I: Interface,
460 P: TryInto<ObjectPath<'p>>,
461 P::Error: Into<Error>,
462 {
463 self.at_ready(path, I::name(), move || Arc::new(RwLock::new(iface)))
464 .await
465 }
466
467 pub(crate) async fn at_ready<'node, 'p, P, F>(
470 &'node self,
471 path: P,
472 name: InterfaceName<'static>,
473 iface_creator: F,
474 ) -> Result<bool>
475 where
476 P: TryInto<ObjectPath<'p>>,
481 P::Error: Into<Error>,
482 F: FnOnce() -> Arc<RwLock<dyn Interface + 'static>>,
483 {
484 let path = path.try_into().map_err(Into::into)?;
485 let mut root = self.root().write().await;
486 let (node, manager_path) = root.get_child_mut(&path, true);
487 let node = node.unwrap();
488 let added = node.at(name.clone(), iface_creator);
489 if added {
490 if name == ObjectManager::name() {
491 let ctxt = SignalContext::new(&self.connection(), path)?;
493 let objects = node.get_managed_objects().await;
494 for (path, owned_interfaces) in objects {
495 let interfaces = owned_interfaces
496 .iter()
497 .map(|(i, props)| {
498 let props = props
499 .iter()
500 .map(|(k, v)| (k.as_str(), Value::from(v)))
501 .collect();
502 (i.into(), props)
503 })
504 .collect();
505 ObjectManager::interfaces_added(&ctxt, &path, &interfaces).await?;
506 }
507 } else if let Some(manager_path) = manager_path {
508 let ctxt = SignalContext::new(&self.connection(), manager_path.clone())?;
509 let mut interfaces = HashMap::new();
510 let owned_props = node.get_properties(name.clone()).await;
511 let props = owned_props
512 .iter()
513 .map(|(k, v)| (k.as_str(), Value::from(v)))
514 .collect();
515 interfaces.insert(name, props);
516
517 ObjectManager::interfaces_added(&ctxt, &path, &interfaces).await?;
518 }
519 }
520
521 Ok(added)
522 }
523
524 pub async fn remove<'p, I, P>(&self, path: P) -> Result<bool>
529 where
530 I: Interface,
531 P: TryInto<ObjectPath<'p>>,
532 P::Error: Into<Error>,
533 {
534 let path = path.try_into().map_err(Into::into)?;
535 let mut root = self.root.write().await;
536 let (node, manager_path) = root.get_child_mut(&path, false);
537 let node = node.ok_or(Error::InterfaceNotFound)?;
538 if !node.remove_interface(I::name()) {
539 return Err(Error::InterfaceNotFound);
540 }
541 if let Some(manager_path) = manager_path {
542 let ctxt = SignalContext::new(&self.connection(), manager_path.clone())?;
543 ObjectManager::interfaces_removed(&ctxt, &path, &[I::name()]).await?;
544 }
545 if node.is_empty() {
546 let mut path_parts = path.rsplit('/').filter(|i| !i.is_empty());
547 let last_part = path_parts.next().unwrap();
548 let ppath = ObjectPath::from_string_unchecked(
549 path_parts.fold(String::new(), |a, p| format!("/{p}{a}")),
550 );
551 root.get_child_mut(&ppath, false)
552 .0
553 .unwrap()
554 .remove_node(last_part);
555 return Ok(true);
556 }
557 Ok(false)
558 }
559
560 pub async fn interface<'p, P, I>(&self, path: P) -> Result<InterfaceRef<I>>
603 where
604 I: Interface,
605 P: TryInto<ObjectPath<'p>>,
606 P::Error: Into<Error>,
607 {
608 let path = path.try_into().map_err(Into::into)?;
609 let root = self.root().read().await;
610 let node = root.get_child(&path).ok_or(Error::InterfaceNotFound)?;
611
612 let lock = node
613 .interface_lock(I::name())
614 .ok_or(Error::InterfaceNotFound)?
615 .clone();
616
617 lock.read()
619 .await
620 .downcast_ref::<I>()
621 .ok_or(Error::InterfaceNotFound)?;
622
623 let conn = self.connection();
624 let ctxt = SignalContext::new(&conn, path).unwrap().into_owned();
626
627 Ok(InterfaceRef {
628 ctxt,
629 lock,
630 phantom: PhantomData,
631 })
632 }
633
634 #[instrument(skip(self, connection))]
635 async fn dispatch_method_call_try(
636 &self,
637 connection: &Connection,
638 msg: &Message,
639 ) -> fdo::Result<Result<()>> {
640 let path = msg
641 .path()
642 .ok_or_else(|| fdo::Error::Failed("Missing object path".into()))?;
643 let iface_name = msg
644 .interface()
645 .ok_or_else(|| fdo::Error::Failed("Missing interface".into()))?;
651 let member = msg
652 .member()
653 .ok_or_else(|| fdo::Error::Failed("Missing member".into()))?;
654
655 let iface = {
658 let root = self.root.read().await;
659 let node = root
660 .get_child(&path)
661 .ok_or_else(|| fdo::Error::UnknownObject(format!("Unknown object '{path}'")))?;
662
663 node.interface_lock(iface_name.as_ref()).ok_or_else(|| {
664 fdo::Error::UnknownInterface(format!("Unknown interface '{iface_name}'"))
665 })?
666 };
667
668 trace!("acquiring read lock on interface `{}`", iface_name);
669 let read_lock = iface.read().await;
670 trace!("acquired read lock on interface `{}`", iface_name);
671 match read_lock.call(self, connection, msg, member.as_ref()) {
672 DispatchResult::NotFound => {
673 return Err(fdo::Error::UnknownMethod(format!(
674 "Unknown method '{member}'"
675 )));
676 }
677 DispatchResult::Async(f) => {
678 return Ok(f.await);
679 }
680 DispatchResult::RequiresMut => {}
681 }
682 drop(read_lock);
683 trace!("acquiring write lock on interface `{}`", iface_name);
684 let mut write_lock = iface.write().await;
685 trace!("acquired write lock on interface `{}`", iface_name);
686 match write_lock.call_mut(self, connection, msg, member.as_ref()) {
687 DispatchResult::NotFound => {}
688 DispatchResult::RequiresMut => {}
689 DispatchResult::Async(f) => {
690 return Ok(f.await);
691 }
692 }
693 drop(write_lock);
694 Err(fdo::Error::UnknownMethod(format!(
695 "Unknown method '{member}'"
696 )))
697 }
698
699 #[instrument(skip(self, connection))]
700 async fn dispatch_method_call(&self, connection: &Connection, msg: &Message) -> Result<()> {
701 match self.dispatch_method_call_try(connection, msg).await {
702 Err(e) => {
703 let hdr = msg.header()?;
704 debug!("Returning error: {}", e);
705 connection.reply_dbus_error(&hdr, e).await?;
706 Ok(())
707 }
708 Ok(r) => r,
709 }
710 }
711
712 #[instrument(skip(self))]
725 pub(crate) async fn dispatch_message(&self, msg: &Message) -> Result<bool> {
726 let conn = self.connection();
727 self.dispatch_method_call(&conn, msg).await?;
728 trace!("Handled: {}", msg);
729
730 Ok(true)
731 }
732
733 pub(crate) fn connection(&self) -> Connection {
734 self.conn
735 .upgrade()
736 .expect("ObjectServer can't exist w/o an associated Connection")
737 }
738}
739
740impl From<crate::blocking::ObjectServer> for ObjectServer {
741 fn from(server: crate::blocking::ObjectServer) -> Self {
742 server.into_inner()
743 }
744}
745
746#[derive(Debug)]
764pub struct ResponseDispatchNotifier<R> {
765 response: R,
766 event: Option<Event>,
767}
768
769impl<R> ResponseDispatchNotifier<R> {
770 pub fn new(response: R) -> (Self, EventListener) {
772 let event = Event::new();
773 let listener = event.listen();
774 (
775 Self {
776 response,
777 event: Some(event),
778 },
779 listener,
780 )
781 }
782}
783
784impl<R> Serialize for ResponseDispatchNotifier<R>
785where
786 R: Serialize,
787{
788 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
789 where
790 S: serde::Serializer,
791 {
792 self.response.serialize(serializer)
793 }
794}
795
796impl<R> Type for ResponseDispatchNotifier<R>
797where
798 R: Type,
799{
800 fn signature() -> Signature<'static> {
801 R::signature()
802 }
803}
804
805impl<T> Drop for ResponseDispatchNotifier<T> {
806 fn drop(&mut self) {
807 if let Some(event) = self.event.take() {
808 event.notify(usize::MAX);
809 }
810 }
811}