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