Skip to main content

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