Skip to main content

input_pipeline/
incoming.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::Transport;
6use anyhow::Context;
7use fidl_fuchsia_io as fio;
8use fuchsia_component::client::Connect;
9use fuchsia_component::directory::{AsRefDirectory, Directory};
10
11#[cfg(feature = "dso")]
12pub use dso::*;
13
14#[cfg(not(feature = "dso"))]
15pub use elf::*;
16
17mod dso {
18    #![cfg(feature = "dso")]
19
20    use super::*;
21    use crate::DriverTransport;
22
23    #[derive(Clone)]
24    pub struct Incoming(std::sync::Arc<fdf_component::Incoming>);
25
26    impl Incoming {
27        pub fn new(incoming: std::sync::Arc<fdf_component::Incoming>) -> Self {
28            Self(incoming)
29        }
30
31        pub fn connect_protocol<T: Connect>(&self) -> Result<T, anyhow::Error> {
32            self.0.connect_protocol().context("connect_protocol")
33        }
34
35        pub fn connect_protocol_next<P: fidl_next::Discoverable>(
36            &self,
37        ) -> Result<fidl_next::ClientEnd<P, Transport>, anyhow::Error> {
38            self.0.connect_protocol_next().context("connect_protocol_next")
39        }
40
41        pub fn connect_protocol_next_at<P: fidl_next::Discoverable>(
42            dir: &impl AsRefDirectory,
43            path: &str,
44        ) -> Result<fidl_next::ClientEnd<P, Transport>, anyhow::Error> {
45            fdf_component::Incoming::connect_protocol_next_at(dir, path)
46                .context("connect_protocol_next_at")
47        }
48
49        pub fn connect_protocol_driver_transport<P: fidl_next::Discoverable>(
50            &self,
51        ) -> Result<fidl_next::ClientEnd<P, DriverTransport>, zx::Status> {
52            self.0.connect_protocol_driver_transport::<P, _>(fdf::CurrentDispatcher)
53        }
54
55        pub fn connect_protocol_driver_transport_at<P: fidl_next::Discoverable>(
56            dir: &impl AsRefDirectory,
57            path: &str,
58        ) -> Result<fidl_next::ClientEnd<P, DriverTransport>, zx::Status> {
59            fdf_component::Incoming::connect_protocol_driver_transport_at::<P, _>(
60                dir,
61                path,
62                fdf::CurrentDispatcher,
63            )
64        }
65    }
66
67    impl Directory for Incoming {
68        fn open(
69            &self,
70            path: &str,
71            flags: fio::Flags,
72            server_end: zx::Channel,
73        ) -> Result<(), anyhow::Error> {
74            self.0.open(path, flags, server_end)
75        }
76    }
77}
78
79mod elf {
80    #![cfg(not(feature = "dso"))]
81
82    use super::*;
83    use fuchsia_component::client::connect;
84
85    #[derive(Clone)]
86    pub struct Incoming;
87
88    impl Incoming {
89        pub fn new() -> Self {
90            Self {}
91        }
92
93        pub fn connect_protocol<T: Connect>(&self) -> Result<T, anyhow::Error> {
94            connect::connect_to_protocol::<T>()
95        }
96
97        pub fn connect_protocol_next<P: fidl_next::Discoverable>(
98            &self,
99        ) -> Result<fidl_next::ClientEnd<P, Transport>, anyhow::Error> {
100            let (client_end, server_end) = zx::Channel::create();
101            fdio::service_connect(&format!("/svc/{}", P::PROTOCOL_NAME), server_end)
102                .context("connect_protocol_next")?;
103            Ok(fidl_next::ClientEnd::<P, zx::Channel>::from_untyped(client_end))
104        }
105
106        pub fn connect_protocol_next_at<P: fidl_next::Discoverable>(
107            dir: &impl AsRefDirectory,
108            path: &str,
109        ) -> Result<fidl_next::ClientEnd<P, Transport>, anyhow::Error> {
110            let (client_end, server_end) = zx::Channel::create();
111            dir.as_ref_directory().open(path, fio::Flags::PROTOCOL_SERVICE, server_end)?;
112            Ok(fidl_next::ClientEnd::<P, zx::Channel>::from_untyped(client_end))
113        }
114    }
115
116    impl Directory for Incoming {
117        fn open(
118            &self,
119            path: &str,
120            flags: fio::Flags,
121            server_end: zx::Channel,
122        ) -> Result<(), anyhow::Error> {
123            fdio::open(path, flags, server_end).context("Directory::open")
124        }
125    }
126}
127
128impl AsRefDirectory for Incoming {
129    fn as_ref_directory(&self) -> &dyn fuchsia_component::directory::Directory {
130        self
131    }
132}