settings/agent/earcons/
utils.rsuse crate::call_async;
use crate::event::Publisher;
use crate::service_context::{ExternalServiceProxy, ServiceContext};
use anyhow::{anyhow, Context as _, Error};
use fidl::endpoints::Proxy as _;
use fidl_fuchsia_media::AudioRenderUsage;
use fidl_fuchsia_media_sounds::{PlayerMarker, PlayerProxy};
use futures::lock::Mutex;
use std::collections::HashSet;
use std::rc::Rc;
use {fidl_fuchsia_io as fio, fuchsia_async as fasync};
fn resource_file(name: &str) -> Result<fidl::endpoints::ClientEnd<fio::FileMarker>, Error> {
let path = format!("/config/data/{name}");
fuchsia_fs::file::open_in_namespace(&path, fio::PERM_READABLE)
.with_context(|| format!("opening resource file: {path}"))?
.into_client_end()
.map_err(|_: fio::FileProxy| {
anyhow!("failed to convert new Proxy to ClientEnd for resource file {path}")
})
}
pub(super) async fn connect_to_sound_player(
publisher: Publisher,
service_context_handle: Rc<ServiceContext>,
sound_player_connection: Rc<Mutex<Option<ExternalServiceProxy<PlayerProxy>>>>,
) {
let mut sound_player_connection_lock = sound_player_connection.lock().await;
if sound_player_connection_lock.is_none() {
*sound_player_connection_lock = service_context_handle
.connect_with_publisher::<PlayerMarker>(publisher)
.await
.context("Connecting to fuchsia.media.sounds.Player")
.map_err(|e| tracing::error!("Failed to connect to fuchsia.media.sounds.Player: {}", e))
.ok()
}
}
pub(super) async fn play_sound<'a>(
sound_player_proxy: &ExternalServiceProxy<PlayerProxy>,
file_name: &'a str,
id: u32,
added_files: Rc<Mutex<HashSet<&'a str>>>,
) -> Result<(), Error> {
if added_files.lock().await.insert(file_name) {
let sound_file_channel = match resource_file(file_name) {
Ok(file) => Some(file),
Err(e) => return Err(anyhow!("[earcons] Failed to convert sound file: {}", e)),
};
if let Some(file_channel) = sound_file_channel {
match call_async!(sound_player_proxy => add_sound_from_file(id, file_channel)).await {
Ok(_) => tracing::debug!("[earcons] Added sound to Player: {}", file_name),
Err(e) => {
return Err(anyhow!("[earcons] Unable to add sound to Player: {}", e));
}
};
}
}
let sound_player_proxy = sound_player_proxy.clone();
fasync::Task::local(async move {
if let Err(e) =
call_async!(sound_player_proxy => play_sound(id, AudioRenderUsage::Background)).await
{
tracing::error!("[earcons] Unable to Play sound from Player: {}", e);
};
})
.detach();
Ok(())
}