settings/
service_context.rs

1// Copyright 2019 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
5#![allow(dead_code)]
6
7use crate::event::{Event, Publisher};
8use crate::message::base::MessengerType;
9use crate::service;
10use anyhow::Error;
11use fidl::endpoints::DiscoverableProtocolMarker;
12use futures::future::OptionFuture;
13use settings_common::service_context::{
14    EventPublisher, ExternalServiceEvent, ExternalServiceProxy as InnerExternalServiceProxy,
15    ServiceContext as InnerServiceContext,
16};
17use std::rc::Rc;
18
19#[cfg(test)]
20use settings_common::service_context::GenerateService;
21
22/// A wrapper around service operations, allowing redirection to a nested
23/// environment.
24pub struct ServiceContext {
25    inner: Rc<InnerServiceContext>,
26    #[allow(dead_code)]
27    delegate: Option<service::message::Delegate>,
28}
29
30impl ServiceContext {
31    #[cfg(test)]
32    pub(crate) fn new(
33        generate_service: Option<GenerateService>,
34        delegate: Option<service::message::Delegate>,
35    ) -> Self {
36        let inner = Rc::new(InnerServiceContext::new(generate_service));
37        Self { inner, delegate }
38    }
39
40    pub(crate) fn new_from_common(
41        inner: Rc<InnerServiceContext>,
42        delegate: Option<service::message::Delegate>,
43    ) -> Self {
44        Self { inner, delegate }
45    }
46
47    pub(crate) fn common_context(&self) -> Rc<InnerServiceContext> {
48        self.inner.clone()
49    }
50
51    #[allow(dead_code)]
52    async fn make_publisher(&self) -> Option<Publisher> {
53        let maybe: OptionFuture<_> = self
54            .delegate
55            .as_ref()
56            .map(|delegate| Publisher::create(delegate, MessengerType::Unbound))
57            .into();
58        maybe.await
59    }
60
61    #[allow(dead_code)]
62    /// Connect to a service with the given ProtocolMarker.
63    ///
64    /// If a GenerateService was specified at creation, the name of the service marker will be used
65    /// to generate a service.
66    pub(crate) async fn connect<P: DiscoverableProtocolMarker>(
67        &self,
68    ) -> Result<ExternalServiceProxy<P::Proxy>, Error> {
69        self.inner.connect::<P, Publisher, _>(|| self.make_publisher()).await
70    }
71
72    pub(crate) async fn connect_with_publisher<P: DiscoverableProtocolMarker>(
73        &self,
74        publisher: Publisher,
75    ) -> Result<ExternalServiceProxy<P::Proxy>, Error> {
76        self.inner.connect_with_publisher::<P, Publisher>(publisher).await
77    }
78}
79
80impl EventPublisher for Publisher {
81    fn send_event(&self, event: ExternalServiceEvent) {
82        Publisher::send_event(self, Event::ExternalServiceEvent(event))
83    }
84}
85
86pub(crate) type ExternalServiceProxy<P> = InnerExternalServiceProxy<P, Publisher>;