1use crate::{Incoming, Node};
6use fuchsia_component::server::{ServiceFs, ServiceObjTrait};
7use log::error;
8use namespace::Namespace;
9use zx::Status;
10
11use fdf::DispatcherRef;
12use fidl_fuchsia_driver_framework::DriverStartArgs;
13
14pub struct DriverContext {
16 pub root_dispatcher: DispatcherRef<'static>,
18 pub start_args: DriverStartArgs,
21 pub incoming: Incoming,
24 #[doc(hidden)]
25 _private: (),
26}
27
28impl DriverContext {
29 pub fn take_node(&mut self) -> Result<Node, Status> {
39 let node_client = self.start_args.node.take().ok_or(Status::INVALID_ARGS)?;
40 Ok(Node::from(node_client.into_proxy()))
41 }
42
43 pub fn serve_outgoing<O: ServiceObjTrait>(
50 &mut self,
51 outgoing_fs: &mut ServiceFs<O>,
52 ) -> Result<(), Status> {
53 let Some(outgoing_dir) = self.start_args.outgoing_dir.take() else {
54 error!("Tried to serve on outgoing directory but it wasn't available");
55 return Err(Status::INVALID_ARGS);
56 };
57 outgoing_fs.serve_connection(outgoing_dir).map_err(|err| {
58 error!("Failed to serve outgoing directory: {err}");
59 Status::INTERNAL
60 })?;
61
62 Ok(())
63 }
64
65 pub(crate) fn new(
66 root_dispatcher: DispatcherRef<'static>,
67 mut start_args: DriverStartArgs,
68 ) -> Result<Self, Status> {
69 let incoming_namespace: Namespace = start_args
70 .incoming
71 .take()
72 .unwrap_or_else(|| vec![])
73 .try_into()
74 .map_err(|_| Status::INVALID_ARGS)?;
75 let incoming = incoming_namespace.try_into().map_err(|_| Status::INVALID_ARGS)?;
76 Ok(DriverContext { root_dispatcher, start_args, incoming, _private: () })
77 }
78
79 pub(crate) fn start_logging(&self, driver_name: &str) -> Result<(), Status> {
80 let log_proxy = match self.incoming.protocol().connect() {
81 Ok(log_proxy) => log_proxy,
82 Err(err) => {
83 eprintln!("Error connecting to log sink proxy at driver startup: {err}. Continuing without logging.");
84 return Ok(());
85 }
86 };
87
88 if let Err(e) = diagnostics_log::initialize(
89 diagnostics_log::PublishOptions::default()
90 .use_log_sink(log_proxy)
91 .tags(&["driver", driver_name]),
92 ) {
93 eprintln!("Error initializing logging at driver startup: {e}");
94 }
95 Ok(())
96 }
97}