Skip to main content

sl4f_lib/bluetooth/
a2dp_facade.rs

1// Copyright 2023 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::common_utils::common::macros::{fx_err_and_bail, with_line};
6use anyhow::Error;
7use fidl_fuchsia_bluetooth_a2dp::{AudioModeMarker, AudioModeProxy, Role};
8use fuchsia_component::client;
9use fuchsia_sync::Mutex;
10use log::info;
11
12#[derive(Debug)]
13pub struct A2dpFacade {
14    audio_mode_proxy: Mutex<Option<AudioModeProxy>>,
15}
16
17/// Perform Bluetooth A2DP functions for both Sink and Source.
18impl A2dpFacade {
19    pub fn new() -> A2dpFacade {
20        A2dpFacade { audio_mode_proxy: Mutex::new(None) }
21    }
22
23    /// Initialize the proxy to the AudioMode service.
24    pub async fn init_audio_mode_proxy(&self) -> Result<(), Error> {
25        let tag = "A2dpFacade::init_audio_mode_proxy";
26        let mut proxy_locked = self.audio_mode_proxy.lock();
27        if proxy_locked.is_some() {
28            info!(
29                tag = &with_line!(tag);
30                "Current A2DP AudioMode proxy: {0:?}", self.audio_mode_proxy
31            );
32            return Ok(());
33        }
34        match client::connect_to_protocol::<AudioModeMarker>() {
35            Ok(proxy) => {
36                *proxy_locked = Some(proxy);
37                Ok(())
38            }
39            Err(err) => {
40                fx_err_and_bail!(
41                    &with_line!(tag),
42                    format_err!("Failed to create A2DP AudioMode proxy: {err}")
43                );
44            }
45        }
46    }
47
48    /// Updates the A2DP Audio Role of the active host device.
49    ///
50    /// # Arguments
51    /// * `role` - The new role to assume. If this role is already set, this is a no-op.
52    pub async fn set_role(&self, role: Role) -> Result<(), Error> {
53        let tag = "A2dpFacade::set_role";
54        let proxy_opt = self.audio_mode_proxy.lock().clone();
55
56        match proxy_opt {
57            Some(proxy) => {
58                proxy.set_role(role).await?;
59                info!("new A2DP audio mode set: {:?}", role);
60                Ok(())
61            }
62            None => {
63                fx_err_and_bail!(&with_line!(tag), "no A2DP Audio Mode Proxy detected");
64            }
65        }
66    }
67}