sandbox/fidl/
dir_connector_router.rs

1// Copyright 2024 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::fidl::router;
6use crate::{ConversionError, DirConnector, Router, RouterResponse};
7use fidl::handle::AsHandleRef;
8use futures::TryStreamExt;
9use std::sync::Arc;
10use vfs::directory::entry::DirectoryEntry;
11use vfs::execution_scope::ExecutionScope;
12use {fidl_fuchsia_component_sandbox as fsandbox, fidl_fuchsia_io as fio};
13
14impl crate::RemotableCapability for Router<DirConnector> {
15    fn try_into_directory_entry(
16        self,
17        scope: ExecutionScope,
18    ) -> Result<Arc<dyn DirectoryEntry>, ConversionError> {
19        Ok(self.into_directory_entry(fio::DirentType::Directory, scope))
20    }
21}
22
23impl From<Router<DirConnector>> for fsandbox::Capability {
24    fn from(router: Router<DirConnector>) -> Self {
25        let (client_end, sender_stream) =
26            fidl::endpoints::create_request_stream::<fsandbox::DirConnectorRouterMarker>();
27        router.serve_and_register(sender_stream, client_end.get_koid().unwrap());
28        fsandbox::Capability::DirConnectorRouter(client_end)
29    }
30}
31
32impl TryFrom<RouterResponse<DirConnector>> for fsandbox::DirConnectorRouterRouteResponse {
33    type Error = fsandbox::RouterError;
34
35    fn try_from(resp: RouterResponse<DirConnector>) -> Result<Self, Self::Error> {
36        match resp {
37            RouterResponse::<DirConnector>::Capability(c) => {
38                Ok(fsandbox::DirConnectorRouterRouteResponse::DirConnector(c.into()))
39            }
40            RouterResponse::<DirConnector>::Unavailable => {
41                Ok(fsandbox::DirConnectorRouterRouteResponse::Unavailable(fsandbox::Unit {}))
42            }
43            RouterResponse::<DirConnector>::Debug(_) => Err(fsandbox::RouterError::NotSupported),
44        }
45    }
46}
47
48impl Router<DirConnector> {
49    async fn serve_router(
50        self,
51        mut stream: fsandbox::DirConnectorRouterRequestStream,
52    ) -> Result<(), fidl::Error> {
53        while let Ok(Some(request)) = stream.try_next().await {
54            match request {
55                fsandbox::DirConnectorRouterRequest::Route { payload, responder } => {
56                    responder.send(router::route_from_fidl(&self, payload).await)?;
57                }
58                fsandbox::DirConnectorRouterRequest::_UnknownMethod { ordinal, .. } => {
59                    log::warn!(
60                        ordinal:%;
61                        "Received unknown DirConnectorRouter request"
62                    );
63                }
64            }
65        }
66        Ok(())
67    }
68
69    /// Serves the `fuchsia.sandbox.Router` protocol and moves ourself into the registry.
70    pub fn serve_and_register(
71        self,
72        stream: fsandbox::DirConnectorRouterRequestStream,
73        koid: zx::Koid,
74    ) {
75        let router = self.clone();
76
77        // Move this capability into the registry.
78        crate::fidl::registry::insert(self.into(), koid, async move {
79            router.serve_router(stream).await.expect("failed to serve Router");
80        });
81    }
82}