blob: 689fd93363d53a4edefa7aaf540f7fb593fe780d [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
anyhow::{Context as _, Error},
fidl::endpoints::{DiscoverableService, ServiceMarker},
fuchsia_component::client::ScopedInstance,
futures::lock::Mutex,
lazy_static::lazy_static,
std::collections::HashMap,
};
lazy_static! {
static ref PROVIDERS: Mutex<HashMap<&'static str, ScopedInstance>> = Mutex::new(HashMap::new());
}
/// Opens a connection to the protocol `T` exposed by `fonts_cm`, starting `fonts_cm` if necessary.
/// If this function is called multiple times with the same `fonts_cm`, the component instance
/// is shared (58150).
// TODO: Instead of configuring fonts through a different manifest and command-line arguments,
// offer a service or directory with the right fonts to the new component instance. This will
// require support to dynamically offer a capability to a component.
pub async fn get_provider<T>(fonts_cm: &'static str) -> Result<T::Proxy, Error>
where
T: ServiceMarker + DiscoverableService,
{
let mut providers = PROVIDERS.lock().await;
if !providers.contains_key(fonts_cm) {
let app = ScopedInstance::new("coll".to_string(), fonts_cm.to_string())
.await
.context("Failed to create dynamic component")?;
providers.insert(fonts_cm, app);
}
let font_provider = providers[&fonts_cm]
.connect_to_protocol_at_exposed_dir::<T>()
.context(format!("Failed to connect to exposed protocol {}", T::DEBUG_NAME))?;
Ok(font_provider)
}