Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b2d6068 authored by Hsin-Yu Chao's avatar Hsin-Yu Chao Committed by Hansong Zhang
Browse files

Add bluetooth_media interface

- Adds the initial dBus template for Bluetooth media
- Connects methods to A2DP topshim

Bug: 189497374
Tag: #floss
Test: dbus-send --system --print-reply \
	--dest=org.chromium.bluetooth \
	/org/chromium/bluetooth/media \
	org.chromium.bluetooth.BluetoothMedia.Initialize

Change-Id: Id8fa7675d9867fa156722c939cba5fc95fb28a78
parent a48b249a
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
use btstack::bluetooth_media::{IBluetoothMedia, IBluetoothMediaCallback};
use btstack::RPCProxy;

use dbus::nonblock::SyncConnection;
use dbus::strings::Path;

use dbus_macros::{dbus_method, dbus_proxy_obj, generate_dbus_exporter};

use dbus_projection::DisconnectWatcher;

use crate::dbus_arg::DBusArg;

#[allow(dead_code)]
struct BluetoothMediaCallbackDBus {}

#[dbus_proxy_obj(BluetoothMediaCallback, "org.chromium.bluetooth.BluetoothMediaCallback")]
impl IBluetoothMediaCallback for BluetoothMediaCallbackDBus {
    #[dbus_method("OnBluetoothAudioDeviceAdded")]
    fn on_bluetooth_audio_device_added(&self, addr: String) {}

    #[dbus_method("OnBluetoothAudioDeviceRemoved")]
    fn on_bluetooth_audio_device_removed(&self, addr: String) {}
}

#[allow(dead_code)]
struct IBluetoothMediaDBus {}

#[generate_dbus_exporter(export_bluetooth_media_dbus_obj, "org.chromium.bluetooth.BluetoothMedia")]
impl IBluetoothMedia for IBluetoothMediaDBus {
    #[dbus_method("RegisterCallback")]
    fn register_callback(&mut self, callback: Box<dyn IBluetoothMediaCallback + Send>) -> bool {
        true
    }

    #[dbus_method("Initialize")]
    fn initialize(&mut self) -> bool {
        true
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ use futures::future;
use btstack::bluetooth::get_bt_dispatcher;
use btstack::bluetooth::{Bluetooth, IBluetooth};
use btstack::bluetooth_gatt::BluetoothGatt;
use btstack::bluetooth_media::BluetoothMedia;
use btstack::Stack;

use std::error::Error;
@@ -23,10 +24,12 @@ use std::sync::{Arc, Mutex};
mod dbus_arg;
mod iface_bluetooth;
mod iface_bluetooth_gatt;
mod iface_bluetooth_media;

const DBUS_SERVICE_NAME: &str = "org.chromium.bluetooth";
const OBJECT_BLUETOOTH: &str = "/org/chromium/bluetooth/adapter";
const OBJECT_BLUETOOTH_GATT: &str = "/org/chromium/bluetooth/gatt";
const OBJECT_BLUETOOTH_MEDIA: &str = "/org/chromium/bluetooth/media";

/// Runs the Bluetooth daemon serving D-Bus IPC.
fn main() -> Result<(), Box<dyn Error>> {
@@ -35,6 +38,8 @@ fn main() -> Result<(), Box<dyn Error>> {
    let intf = Arc::new(Mutex::new(get_btinterface().unwrap()));
    let bluetooth = Arc::new(Mutex::new(Box::new(Bluetooth::new(tx.clone(), intf.clone()))));
    let bluetooth_gatt = Arc::new(Mutex::new(Box::new(BluetoothGatt::new(intf.clone()))));
    let bluetooth_media =
        Arc::new(Mutex::new(Box::new(BluetoothMedia::new(tx.clone(), intf.clone()))));

    // Args don't include arg[0] which is the binary name
    let all_args = std::env::args().collect::<Vec<String>>();
@@ -91,6 +96,14 @@ fn main() -> Result<(), Box<dyn Error>> {
            disconnect_watcher.clone(),
        );

        iface_bluetooth_media::export_bluetooth_media_dbus_obj(
            String::from(OBJECT_BLUETOOTH_MEDIA),
            conn.clone(),
            &mut cr,
            bluetooth_media,
            disconnect_watcher.clone(),
        );

        conn.start_receive(
            MatchRule::new_method_call(),
            Box::new(move |msg, conn| {
+79 −0
Original line number Diff line number Diff line
//! Anything related to audio and media API.

use bt_topshim::btif::BluetoothInterface;
use bt_topshim::profiles::a2dp::{A2dp, A2dpCallbacks, A2dpCallbacksDispatcher};
use bt_topshim::topstack;

use std::sync::Arc;
use std::sync::Mutex;

use tokio::sync::mpsc::Sender;

use crate::Message;

pub trait IBluetoothMedia {
    ///
    fn register_callback(&mut self, callback: Box<dyn IBluetoothMediaCallback + Send>) -> bool;

    ///
    fn initialize(&mut self) -> bool;
}

pub trait IBluetoothMediaCallback {
    ///
    fn on_bluetooth_audio_device_added(&self, addr: String);

    ///
    fn on_bluetooth_audio_device_removed(&self, addr: String);
}

pub struct BluetoothMedia {
    intf: Arc<Mutex<BluetoothInterface>>,
    initialized: bool,
    callbacks: Vec<(u32, Box<dyn IBluetoothMediaCallback + Send>)>,
    callback_last_id: u32,
    tx: Sender<Message>,
    a2dp: Option<A2dp>,
}

impl BluetoothMedia {
    pub fn new(tx: Sender<Message>, intf: Arc<Mutex<BluetoothInterface>>) -> BluetoothMedia {
        BluetoothMedia {
            intf,
            initialized: false,
            callbacks: vec![],
            callback_last_id: 0,
            tx,
            a2dp: None,
        }
    }
}

fn get_a2dp_dispatcher(tx: Sender<Message>) -> A2dpCallbacksDispatcher {
    A2dpCallbacksDispatcher {
        dispatch: Box::new(move |cb| {
            let txl = tx.clone();
            topstack::get_runtime().spawn(async move {
                let _ = txl.send(Message::A2dp(cb)).await;
            });
        }),
    }
}

impl IBluetoothMedia for BluetoothMedia {
    fn register_callback(&mut self, callback: Box<dyn IBluetoothMediaCallback + Send>) -> bool {
        self.callback_last_id += 1;
        self.callbacks.push((self.callback_last_id, callback));
        true
    }

    fn initialize(&mut self) -> bool {
        self.initialized = true;

        // TEST A2dp
        let a2dp_dispatcher = get_a2dp_dispatcher(self.tx.clone());
        self.a2dp = Some(A2dp::new(&self.intf.lock().unwrap()));
        self.a2dp.as_mut().unwrap().initialize(a2dp_dispatcher);
        true
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -8,8 +8,10 @@ extern crate num_derive;

pub mod bluetooth;
pub mod bluetooth_gatt;
pub mod bluetooth_media;

use bt_topshim::btif::BaseCallbacks;
use bt_topshim::profiles::a2dp::A2dpCallbacks;

use std::convert::TryInto;
use std::fmt::{Debug, Formatter, Result};
@@ -88,6 +90,7 @@ impl BDAddr {

/// Message types that are sent to the stack main dispatch loop.
pub enum Message {
    A2dp(A2dpCallbacks),
    Base(BaseCallbacks),
    BluetoothCallbackDisconnected(u32),
}
@@ -112,6 +115,10 @@ impl Stack {
            }

            match m.unwrap() {
                Message::A2dp(a) => {
                    //
                    println!("RX {:?}", a);
                }
                Message::Base(b) => {
                    bluetooth.lock().unwrap().dispatch_base_callbacks(b);
                }