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