Loading system/gd/rust/linux/service/src/iface_bluetooth_media.rs +6 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,12 @@ impl IBluetoothMediaCallback for BluetoothMediaCallbackDBus { #[dbus_method("OnBluetoothAudioDeviceRemoved")] fn on_bluetooth_audio_device_removed(&self, addr: String) {} #[dbus_method("OnAbsoluteVolumeSupportedChanged")] fn on_absolute_volume_supported_changed(&self, supported: bool) {} #[dbus_method("OnAbsoluteVolumeChanged")] fn on_absolute_volume_changed(&self, volume: i32) {} } #[allow(dead_code)] Loading system/gd/rust/linux/stack/src/bluetooth_media.rs +35 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ use bt_topshim::profiles::a2dp::{ A2dpCodecConfig, A2dpCodecIndex, A2dpCodecSampleRate, BtavConnectionState, PresentationPosition, }; use bt_topshim::profiles::avrcp::Avrcp; use bt_topshim::profiles::avrcp::{Avrcp, AvrcpCallbacks, AvrcpCallbacksDispatcher}; use bt_topshim::topstack; use std::collections::HashMap; Loading Loading @@ -55,6 +55,12 @@ pub trait IBluetoothMediaCallback { /// fn on_bluetooth_audio_device_removed(&self, addr: String); /// fn on_absolute_volume_supported_changed(&self, supported: bool); /// fn on_absolute_volume_changed(&self, volume: i32); } pub struct BluetoothMedia { Loading Loading @@ -131,6 +137,21 @@ impl BluetoothMedia { } } pub fn dispatch_avrcp_callbacks(&mut self, cb: AvrcpCallbacks) { match cb { AvrcpCallbacks::AvrcpAbsoluteVolumeEnabled(supported) => { self.for_all_callbacks(|callback| { callback.on_absolute_volume_supported_changed(supported); }); } AvrcpCallbacks::AvrcpAbsoluteVolumeUpdate(volume) => { self.for_all_callbacks(|callback| { callback.on_absolute_volume_changed(i32::from(volume)); }); } } } fn for_all_callbacks<F: Fn(&Box<dyn IBluetoothMediaCallback + Send>)>(&self, f: F) { for callback in &self.callbacks { f(&callback.1); Loading @@ -149,6 +170,17 @@ fn get_a2dp_dispatcher(tx: Sender<Message>) -> A2dpCallbacksDispatcher { } } fn get_avrcp_dispatcher(tx: Sender<Message>) -> AvrcpCallbacksDispatcher { AvrcpCallbacksDispatcher { dispatch: Box::new(move |cb| { let txl = tx.clone(); topstack::get_runtime().spawn(async move { let _ = txl.send(Message::Avrcp(cb)).await; }); }), } } impl IBluetoothMedia for BluetoothMedia { fn register_callback(&mut self, callback: Box<dyn IBluetoothMediaCallback + Send>) -> bool { self.callback_last_id += 1; Loading @@ -165,8 +197,9 @@ impl IBluetoothMedia for BluetoothMedia { self.a2dp.as_mut().unwrap().initialize(a2dp_dispatcher); // AVRCP let avrcp_dispatcher = get_avrcp_dispatcher(self.tx.clone()); self.avrcp = Some(Avrcp::new(&self.intf.lock().unwrap())); self.avrcp.as_mut().unwrap().initialize(); self.avrcp.as_mut().unwrap().initialize(avrcp_dispatcher); true } Loading system/gd/rust/linux/stack/src/lib.rs +6 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ pub mod bluetooth_media; use bt_topshim::btif::BaseCallbacks; use bt_topshim::profiles::a2dp::A2dpCallbacks; use bt_topshim::profiles::avrcp::AvrcpCallbacks; use bt_topshim::profiles::gatt::GattClientCallbacks; use bt_topshim::profiles::gatt::GattServerCallbacks; Loading @@ -30,6 +31,7 @@ use crate::bluetooth_media::BluetoothMedia; /// Message types that are sent to the stack main dispatch loop. pub enum Message { A2dp(A2dpCallbacks), Avrcp(AvrcpCallbacks), Base(BaseCallbacks), GattClient(GattClientCallbacks), GattServer(GattServerCallbacks), Loading Loading @@ -65,6 +67,10 @@ impl Stack { bluetooth_media.lock().unwrap().dispatch_a2dp_callbacks(a); } Message::Avrcp(av) => { bluetooth_media.lock().unwrap().dispatch_avrcp_callbacks(av); } Message::Base(b) => { bluetooth.lock().unwrap().dispatch_base_callbacks(b); } Loading system/gd/rust/topshim/btav/btav_shim.cc +29 −7 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ #include "base/callback.h" #include "rust/cxx.h" #include "src/profiles/a2dp.rs.h" #include "src/profiles/avrcp.rs.h" namespace rusty = ::bluetooth::topshim::rust; namespace bluetooth::avrcp { class AvrcpMediaInterfaceImpl : public MediaInterface { Loading Loading @@ -60,13 +63,34 @@ class AvrcpMediaInterfaceImpl : public MediaInterface { class VolumeInterfaceImpl : public VolumeInterface { public: void DeviceConnected([[maybe_unused]] const RawAddress& bdaddr) override {} void DeviceConnected([[maybe_unused]] const RawAddress& bdaddr) override { rusty::avrcp_absolute_volume_enabled(false); } void DeviceConnected([[maybe_unused]] const RawAddress& bdaddr, VolumeChangedCb cb) override { volumeCb = std::move(cb); rusty::avrcp_absolute_volume_enabled(true); } void DeviceDisconnected([[maybe_unused]] const RawAddress& bdaddr) override { volumeCb.Reset(); rusty::avrcp_absolute_volume_enabled(false); } // Set TG's (Android, ChromeOS) volume. void SetVolume(int8_t volume) override { rusty::avrcp_absolute_volume_update(volume); } void DeviceConnected([[maybe_unused]] const RawAddress& bdaddr, [[maybe_unused]] VolumeChangedCb cb) override {} // Set CT's (headsets, speakers) volume. void SetDeviceVolume(int8_t volume) { if (!volumeCb || volume < 0) return; void DeviceDisconnected([[maybe_unused]] const RawAddress& bdaddr) override {} volumeCb.Run(volume); } void SetVolume([[maybe_unused]] int8_t volume) override {} private: VolumeInterface::VolumeChangedCb volumeCb; }; } // namespace bluetooth::avrcp Loading @@ -78,8 +102,6 @@ namespace internal { static A2dpIntf* g_a2dpif; static AvrcpIntf* g_avrcpif; namespace rusty = ::bluetooth::topshim::rust; static RustRawAddress to_rust_address(const RawAddress& address) { RustRawAddress raddr; std::copy(std::begin(address.address), std::end(address.address), std::begin(raddr.address)); Loading Loading @@ -272,7 +294,7 @@ int AvrcpIntf::disconnect(RustRawAddress bt_addr) { } void AvrcpIntf::set_volume(int8_t volume) { return mVolumeInterface.SetVolume(volume); return mVolumeInterface.SetDeviceVolume(volume); } } // namespace rust } // namespace topshim Loading system/gd/rust/topshim/facade/src/media_service.rs +6 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ use bt_topshim::btif::BluetoothInterface; use bt_topshim::profiles::a2dp::{A2dp, A2dpCallbacksDispatcher, A2dpSink}; use bt_topshim::profiles::avrcp::Avrcp; use bt_topshim::profiles::avrcp::{Avrcp, AvrcpCallbacksDispatcher}; use bt_topshim_facade_protobuf::facade::{ A2dpSourceConnectRequest, A2dpSourceConnectResponse, StartA2dpRequest, StartA2dpResponse, }; Loading @@ -17,6 +17,10 @@ fn get_a2dp_dispatcher() -> A2dpCallbacksDispatcher { A2dpCallbacksDispatcher { dispatch: Box::new(move |_cb| {}) } } fn get_avrcp_dispatcher() -> AvrcpCallbacksDispatcher { AvrcpCallbacksDispatcher { dispatch: Box::new(move |_cb| {}) } } /// Main object for Media facade service #[derive(Clone)] pub struct MediaServiceImpl { Loading @@ -33,7 +37,7 @@ impl MediaServiceImpl { let btif_a2dp_sink = A2dpSink::new(&btif_intf.lock().unwrap()); let mut btif_avrcp = Avrcp::new(&btif_intf.lock().unwrap()); btif_a2dp.initialize(get_a2dp_dispatcher()); btif_avrcp.initialize(); btif_avrcp.initialize(get_avrcp_dispatcher()); create_media_service(Self { rt, Loading Loading
system/gd/rust/linux/service/src/iface_bluetooth_media.rs +6 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,12 @@ impl IBluetoothMediaCallback for BluetoothMediaCallbackDBus { #[dbus_method("OnBluetoothAudioDeviceRemoved")] fn on_bluetooth_audio_device_removed(&self, addr: String) {} #[dbus_method("OnAbsoluteVolumeSupportedChanged")] fn on_absolute_volume_supported_changed(&self, supported: bool) {} #[dbus_method("OnAbsoluteVolumeChanged")] fn on_absolute_volume_changed(&self, volume: i32) {} } #[allow(dead_code)] Loading
system/gd/rust/linux/stack/src/bluetooth_media.rs +35 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ use bt_topshim::profiles::a2dp::{ A2dpCodecConfig, A2dpCodecIndex, A2dpCodecSampleRate, BtavConnectionState, PresentationPosition, }; use bt_topshim::profiles::avrcp::Avrcp; use bt_topshim::profiles::avrcp::{Avrcp, AvrcpCallbacks, AvrcpCallbacksDispatcher}; use bt_topshim::topstack; use std::collections::HashMap; Loading Loading @@ -55,6 +55,12 @@ pub trait IBluetoothMediaCallback { /// fn on_bluetooth_audio_device_removed(&self, addr: String); /// fn on_absolute_volume_supported_changed(&self, supported: bool); /// fn on_absolute_volume_changed(&self, volume: i32); } pub struct BluetoothMedia { Loading Loading @@ -131,6 +137,21 @@ impl BluetoothMedia { } } pub fn dispatch_avrcp_callbacks(&mut self, cb: AvrcpCallbacks) { match cb { AvrcpCallbacks::AvrcpAbsoluteVolumeEnabled(supported) => { self.for_all_callbacks(|callback| { callback.on_absolute_volume_supported_changed(supported); }); } AvrcpCallbacks::AvrcpAbsoluteVolumeUpdate(volume) => { self.for_all_callbacks(|callback| { callback.on_absolute_volume_changed(i32::from(volume)); }); } } } fn for_all_callbacks<F: Fn(&Box<dyn IBluetoothMediaCallback + Send>)>(&self, f: F) { for callback in &self.callbacks { f(&callback.1); Loading @@ -149,6 +170,17 @@ fn get_a2dp_dispatcher(tx: Sender<Message>) -> A2dpCallbacksDispatcher { } } fn get_avrcp_dispatcher(tx: Sender<Message>) -> AvrcpCallbacksDispatcher { AvrcpCallbacksDispatcher { dispatch: Box::new(move |cb| { let txl = tx.clone(); topstack::get_runtime().spawn(async move { let _ = txl.send(Message::Avrcp(cb)).await; }); }), } } impl IBluetoothMedia for BluetoothMedia { fn register_callback(&mut self, callback: Box<dyn IBluetoothMediaCallback + Send>) -> bool { self.callback_last_id += 1; Loading @@ -165,8 +197,9 @@ impl IBluetoothMedia for BluetoothMedia { self.a2dp.as_mut().unwrap().initialize(a2dp_dispatcher); // AVRCP let avrcp_dispatcher = get_avrcp_dispatcher(self.tx.clone()); self.avrcp = Some(Avrcp::new(&self.intf.lock().unwrap())); self.avrcp.as_mut().unwrap().initialize(); self.avrcp.as_mut().unwrap().initialize(avrcp_dispatcher); true } Loading
system/gd/rust/linux/stack/src/lib.rs +6 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ pub mod bluetooth_media; use bt_topshim::btif::BaseCallbacks; use bt_topshim::profiles::a2dp::A2dpCallbacks; use bt_topshim::profiles::avrcp::AvrcpCallbacks; use bt_topshim::profiles::gatt::GattClientCallbacks; use bt_topshim::profiles::gatt::GattServerCallbacks; Loading @@ -30,6 +31,7 @@ use crate::bluetooth_media::BluetoothMedia; /// Message types that are sent to the stack main dispatch loop. pub enum Message { A2dp(A2dpCallbacks), Avrcp(AvrcpCallbacks), Base(BaseCallbacks), GattClient(GattClientCallbacks), GattServer(GattServerCallbacks), Loading Loading @@ -65,6 +67,10 @@ impl Stack { bluetooth_media.lock().unwrap().dispatch_a2dp_callbacks(a); } Message::Avrcp(av) => { bluetooth_media.lock().unwrap().dispatch_avrcp_callbacks(av); } Message::Base(b) => { bluetooth.lock().unwrap().dispatch_base_callbacks(b); } Loading
system/gd/rust/topshim/btav/btav_shim.cc +29 −7 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ #include "base/callback.h" #include "rust/cxx.h" #include "src/profiles/a2dp.rs.h" #include "src/profiles/avrcp.rs.h" namespace rusty = ::bluetooth::topshim::rust; namespace bluetooth::avrcp { class AvrcpMediaInterfaceImpl : public MediaInterface { Loading Loading @@ -60,13 +63,34 @@ class AvrcpMediaInterfaceImpl : public MediaInterface { class VolumeInterfaceImpl : public VolumeInterface { public: void DeviceConnected([[maybe_unused]] const RawAddress& bdaddr) override {} void DeviceConnected([[maybe_unused]] const RawAddress& bdaddr) override { rusty::avrcp_absolute_volume_enabled(false); } void DeviceConnected([[maybe_unused]] const RawAddress& bdaddr, VolumeChangedCb cb) override { volumeCb = std::move(cb); rusty::avrcp_absolute_volume_enabled(true); } void DeviceDisconnected([[maybe_unused]] const RawAddress& bdaddr) override { volumeCb.Reset(); rusty::avrcp_absolute_volume_enabled(false); } // Set TG's (Android, ChromeOS) volume. void SetVolume(int8_t volume) override { rusty::avrcp_absolute_volume_update(volume); } void DeviceConnected([[maybe_unused]] const RawAddress& bdaddr, [[maybe_unused]] VolumeChangedCb cb) override {} // Set CT's (headsets, speakers) volume. void SetDeviceVolume(int8_t volume) { if (!volumeCb || volume < 0) return; void DeviceDisconnected([[maybe_unused]] const RawAddress& bdaddr) override {} volumeCb.Run(volume); } void SetVolume([[maybe_unused]] int8_t volume) override {} private: VolumeInterface::VolumeChangedCb volumeCb; }; } // namespace bluetooth::avrcp Loading @@ -78,8 +102,6 @@ namespace internal { static A2dpIntf* g_a2dpif; static AvrcpIntf* g_avrcpif; namespace rusty = ::bluetooth::topshim::rust; static RustRawAddress to_rust_address(const RawAddress& address) { RustRawAddress raddr; std::copy(std::begin(address.address), std::end(address.address), std::begin(raddr.address)); Loading Loading @@ -272,7 +294,7 @@ int AvrcpIntf::disconnect(RustRawAddress bt_addr) { } void AvrcpIntf::set_volume(int8_t volume) { return mVolumeInterface.SetVolume(volume); return mVolumeInterface.SetDeviceVolume(volume); } } // namespace rust } // namespace topshim Loading
system/gd/rust/topshim/facade/src/media_service.rs +6 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ use bt_topshim::btif::BluetoothInterface; use bt_topshim::profiles::a2dp::{A2dp, A2dpCallbacksDispatcher, A2dpSink}; use bt_topshim::profiles::avrcp::Avrcp; use bt_topshim::profiles::avrcp::{Avrcp, AvrcpCallbacksDispatcher}; use bt_topshim_facade_protobuf::facade::{ A2dpSourceConnectRequest, A2dpSourceConnectResponse, StartA2dpRequest, StartA2dpResponse, }; Loading @@ -17,6 +17,10 @@ fn get_a2dp_dispatcher() -> A2dpCallbacksDispatcher { A2dpCallbacksDispatcher { dispatch: Box::new(move |_cb| {}) } } fn get_avrcp_dispatcher() -> AvrcpCallbacksDispatcher { AvrcpCallbacksDispatcher { dispatch: Box::new(move |_cb| {}) } } /// Main object for Media facade service #[derive(Clone)] pub struct MediaServiceImpl { Loading @@ -33,7 +37,7 @@ impl MediaServiceImpl { let btif_a2dp_sink = A2dpSink::new(&btif_intf.lock().unwrap()); let mut btif_avrcp = Avrcp::new(&btif_intf.lock().unwrap()); btif_a2dp.initialize(get_a2dp_dispatcher()); btif_avrcp.initialize(); btif_avrcp.initialize(get_avrcp_dispatcher()); create_media_service(Self { rt, Loading