sandbox/fidl/
connector.rs1use crate::fidl::registry;
6use crate::{Connector, ConversionError, Message, Receiver, WeakInstanceToken};
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 _token: WeakInstanceToken,
37 ) -> Result<Arc<dyn DirectoryEntry>, ConversionError> {
38 Ok(vfs::service::endpoint(move |_scope, server_end| {
39 let _ = self.send_channel(server_end.into_zx_channel().into());
40 }))
41 }
42}
43
44impl From<Connector> for fsandbox::Connector {
45 fn from(value: Connector) -> Self {
46 fsandbox::Connector { token: registry::insert_token(value.into()) }
47 }
48}
49
50impl crate::fidl::IntoFsandboxCapability for Connector {
51 fn into_fsandbox_capability(self, _token: WeakInstanceToken) -> fsandbox::Capability {
52 fsandbox::Capability::Connector(self.into())
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use assert_matches::assert_matches;
60 use fidl::endpoints::ClientEnd;
61 use fidl_fuchsia_io as fio;
62 use futures::StreamExt;
63 use vfs::ToObjectRequest;
64 use vfs::directory::entry::OpenRequest;
65 use vfs::execution_scope::ExecutionScope;
66
67 #[fuchsia::test]
69 async fn unwrap_server_end_or_serve_node_node_reference_and_describe() {
70 let receiver = {
71 let (receiver, sender) = Connector::new();
72 let open: crate::DirEntry = sender.into();
73 let (client, server) = fidl::endpoints::create_proxy::<fio::NodeMarker>();
74 const FLAGS: fio::Flags =
75 fio::Flags::PROTOCOL_NODE.union(fio::Flags::FLAG_SEND_REPRESENTATION);
76 FLAGS.to_object_request(server.into_channel()).handle(|request| {
77 open.open_entry(OpenRequest::new(
78 ExecutionScope::new(),
79 FLAGS,
80 vfs::Path::dot(),
81 request,
82 ))
83 });
84
85 let result = client.take_event_stream().next().await.unwrap();
87 assert_matches!(
88 result,
89 Ok(fio::NodeEvent::OnRepresentation { payload: fio::Representation::Node(_) })
90 );
91
92 receiver
93 };
94
95 assert_matches!(receiver.receive().await, None);
97 }
98
99 #[fuchsia::test]
101 async fn unwrap_server_end_or_serve_node_empty() {
102 let (receiver, sender) = Connector::new();
103 let open: crate::DirEntry = sender.into();
104
105 let (client_end, server_end) = Channel::create();
106 const FLAGS: fio::Flags = fio::Flags::PROTOCOL_SERVICE;
108 FLAGS.to_object_request(server_end).handle(|request| {
109 open.open_entry(OpenRequest::new(
110 ExecutionScope::new(),
111 FLAGS,
112 vfs::Path::dot(),
113 request,
114 ))
115 });
116 assert_matches!(receiver.receive().await, Some(_));
118
119 let client_end: ClientEnd<fio::NodeMarker> = client_end.into();
122 let node: fio::NodeProxy = client_end.into_proxy();
123 assert_matches!(node.take_event_stream().next().await, None);
124 }
125}