sandbox/fidl/
connector.rs1use crate::fidl::registry;
6use crate::{Connector, ConversionError, Message, Receiver};
7use fidl::endpoints::ClientEnd;
8use fidl::handle::Channel;
9use futures::channel::mpsc;
10use std::sync::Arc;
11use vfs::directory::entry::DirectoryEntry;
12use vfs::execution_scope::ExecutionScope;
13use {fidl_fuchsia_component_sandbox as fsandbox, fuchsia_async as fasync};
14
15impl Connector {
16 pub(crate) fn send_channel(&self, channel: Channel) -> Result<(), ()> {
17 self.send(Message { channel })
18 }
19
20 pub(crate) fn new_with_fidl_receiver(
21 receiver_client: ClientEnd<fsandbox::ReceiverMarker>,
22 scope: &fasync::Scope,
23 ) -> Self {
24 let (sender, receiver) = mpsc::unbounded();
25 let receiver = Receiver::new(receiver);
26 scope.spawn(receiver.handle_receiver(receiver_client.into_proxy()));
28 Self::new_sendable(sender)
29 }
30}
31
32impl crate::RemotableCapability for Connector {
33 fn try_into_directory_entry(
34 self,
35 _scope: ExecutionScope,
36 ) -> Result<Arc<dyn DirectoryEntry>, ConversionError> {
37 Ok(vfs::service::endpoint(move |_scope, server_end| {
38 let _ = self.send_channel(server_end.into_zx_channel().into());
39 }))
40 }
41}
42
43impl From<Connector> for fsandbox::Connector {
44 fn from(value: Connector) -> Self {
45 fsandbox::Connector { token: registry::insert_token(value.into()) }
46 }
47}
48
49impl From<Connector> for fsandbox::Capability {
50 fn from(connector: Connector) -> Self {
51 fsandbox::Capability::Connector(connector.into())
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use assert_matches::assert_matches;
59 use fidl::endpoints::ClientEnd;
60 use fidl_fuchsia_io as fio;
61 use futures::StreamExt;
62 use vfs::directory::entry::OpenRequest;
63 use vfs::execution_scope::ExecutionScope;
64 use vfs::ToObjectRequest;
65
66 #[fuchsia::test]
68 async fn unwrap_server_end_or_serve_node_node_reference_and_describe() {
69 let receiver = {
70 let (receiver, sender) = Connector::new();
71 let open: crate::DirEntry = sender.into();
72 let (client, server) = fidl::endpoints::create_proxy::<fio::NodeMarker>();
73 const FLAGS: fio::Flags =
74 fio::Flags::PROTOCOL_NODE.union(fio::Flags::FLAG_SEND_REPRESENTATION);
75 FLAGS.to_object_request(server.into_channel()).handle(|request| {
76 open.open_entry(OpenRequest::new(
77 ExecutionScope::new(),
78 FLAGS,
79 vfs::Path::dot(),
80 request,
81 ))
82 });
83
84 let result = client.take_event_stream().next().await.unwrap();
86 assert_matches!(
87 result,
88 Ok(fio::NodeEvent::OnRepresentation { payload: fio::Representation::Node(_) })
89 );
90
91 receiver
92 };
93
94 assert_matches!(receiver.receive().await, None);
96 }
97
98 #[fuchsia::test]
100 async fn unwrap_server_end_or_serve_node_empty() {
101 let (receiver, sender) = Connector::new();
102 let open: crate::DirEntry = sender.into();
103
104 let (client_end, server_end) = Channel::create();
105 const FLAGS: fio::Flags = fio::Flags::PROTOCOL_SERVICE;
107 FLAGS.to_object_request(server_end).handle(|request| {
108 open.open_entry(OpenRequest::new(
109 ExecutionScope::new(),
110 FLAGS,
111 vfs::Path::dot(),
112 request,
113 ))
114 });
115 assert_matches!(receiver.receive().await, Some(_));
117
118 let client_end: ClientEnd<fio::NodeMarker> = client_end.into();
121 let node: fio::NodeProxy = client_end.into_proxy();
122 assert_matches!(node.take_event_stream().next().await, None);
123 }
124}