Loading system/gd/rust/linux/stack/src/bluetooth_media.rs +55 −39 Original line number Diff line number Diff line //! Anything related to audio and media API. use bt_topshim::btif::{ BluetoothInterface, BtBondState, BtConnectionDirection, BtStatus, BtTransport, DisplayAddress, RawAddress, ToggleableProfile, BluetoothInterface, BtBondState, BtStatus, BtTransport, DisplayAddress, RawAddress, ToggleableProfile, }; use bt_topshim::profiles::a2dp::{ A2dp, A2dpCallbacks, A2dpCallbacksDispatcher, A2dpCodecBitsPerSample, A2dpCodecChannelMode, Loading Loading @@ -472,7 +472,8 @@ pub struct BluetoothMedia { adapter: Arc<Mutex<Box<Bluetooth>>>, a2dp: A2dp, avrcp: Avrcp, avrcp_direction: BtConnectionDirection, avrcp_address: Option<RawAddress>, avrcp_states: HashMap<RawAddress, BtavConnectionState>, a2dp_states: HashMap<RawAddress, BtavConnectionState>, a2dp_audio_state: HashMap<RawAddress, BtavAudioState>, a2dp_has_interrupted_stream: bool, // Only used for qualification. Loading Loading @@ -548,7 +549,8 @@ impl BluetoothMedia { adapter, a2dp, avrcp, avrcp_direction: BtConnectionDirection::Unknown, avrcp_address: None, avrcp_states: HashMap::new(), a2dp_states: HashMap::new(), a2dp_audio_state: HashMap::new(), a2dp_has_interrupted_stream: false, Loading Loading @@ -1307,6 +1309,31 @@ impl BluetoothMedia { supported ); // If is device initiated the AVRCP connection, emit a fake connecting state as // stack don't receive one. if self.avrcp_states.get(&addr) != Some(&BtavConnectionState::Connecting) { metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Connecting as u32, ); } metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Connected as u32, ); self.avrcp_states.insert(addr, BtavConnectionState::Connected); if self.avrcp_address.is_some() { warn!("Another AVRCP connection exists. Disconnect {}", DisplayAddress(&addr)); self.avrcp.disconnect(addr); return; } self.avrcp_address = Some(addr); match self.uinput.create(self.adapter_get_remote_name(addr), addr.to_string()) { Ok(()) => info!("uinput device created for: {}", DisplayAddress(&addr)), Err(e) => warn!("{}", e), Loading @@ -1325,30 +1352,34 @@ impl BluetoothMedia { } self.absolute_volume = supported; self.add_connected_profile(addr, Profile::AvrcpController); } AvrcpCallbacks::AvrcpDeviceDisconnected(addr) => { info!("[{}]: avrcp disconnected.", DisplayAddress(&addr)); // If is device initiated the AVRCP connection, emit a fake connecting state as // stack don't receive one. if self.avrcp_direction != BtConnectionDirection::Outgoing { // If the peer device initiated the AVRCP disconnection, emit a fake connecting // state as stack don't receive one. if self.avrcp_states.get(&addr) != Some(&BtavConnectionState::Disconnecting) { metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Connecting as u32, BtavConnectionState::Disconnecting as u32, ); } metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Connected as u32, BtavConnectionState::Disconnected as u32, ); // Reset direction to unknown. self.avrcp_direction = BtConnectionDirection::Unknown; self.avrcp_states.remove(&addr); self.add_connected_profile(addr, Profile::AvrcpController); if self.avrcp_address != Some(addr) { // Ignore disconnection to address we don't care return; } AvrcpCallbacks::AvrcpDeviceDisconnected(addr) => { info!("[{}]: avrcp disconnected.", DisplayAddress(&addr)); self.avrcp_address = None; self.uinput.close(addr.to_string()); Loading @@ -1362,25 +1393,6 @@ impl BluetoothMedia { None => false, }; // If the peer device initiated the AVRCP disconnection, emit a fake connecting // state as stack don't receive one. if self.avrcp_direction != BtConnectionDirection::Outgoing { metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Disconnecting as u32, ); } metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Disconnected as u32, ); // Reset direction to unknown. self.avrcp_direction = BtConnectionDirection::Unknown; self.rm_connected_profile(addr, Profile::AvrcpController, is_profile_critical); } AvrcpCallbacks::AvrcpAbsoluteVolumeUpdate(volume) => { Loading Loading @@ -3336,11 +3348,11 @@ impl IBluetoothMedia for BluetoothMedia { BtStatus::Success, BtavConnectionState::Connecting as u32, ); self.avrcp_direction = BtConnectionDirection::Outgoing; self.avrcp_states.insert(addr, BtavConnectionState::Connecting); let status = self.avrcp.connect(addr); if BtStatus::Success != status { // Reset direction to unknown. self.avrcp_direction = BtConnectionDirection::Unknown; self.avrcp_states.remove(&addr); metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, Loading Loading @@ -3463,11 +3475,11 @@ impl IBluetoothMedia for BluetoothMedia { BtStatus::Success, BtavConnectionState::Disconnecting as u32, ); self.avrcp_direction = BtConnectionDirection::Outgoing; self.avrcp_states.insert(addr, BtavConnectionState::Disconnecting); let status = self.avrcp.disconnect(addr); if BtStatus::Success != status { // Reset direction to unknown. self.avrcp_direction = BtConnectionDirection::Unknown; self.avrcp_states.remove(&addr); metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, Loading Loading @@ -3569,6 +3581,10 @@ impl IBluetoothMedia for BluetoothMedia { } fn set_volume(&mut self, volume: u8) { if self.avrcp_address.is_none() { return; } // Guard the range 0-127 by the try_from cast from u8 to i8. let vol = match i8::try_from(volume) { Ok(val) => val, Loading @@ -3578,7 +3594,7 @@ impl IBluetoothMedia for BluetoothMedia { } }; self.avrcp.set_volume(vol); self.avrcp.set_volume(self.avrcp_address.unwrap(), vol); } fn set_hfp_volume(&mut self, volume: u8, addr: RawAddress) { Loading system/gd/rust/topshim/btav/btav_shim.cc +13 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "rust/topshim/btav/btav_shim.h" #include <cstdio> #include <map> #include <memory> #include "base/functional/callback.h" Loading Loading @@ -156,12 +157,12 @@ public: } void DeviceConnected(const RawAddress& addr, VolumeChangedCb cb) override { volumeCb = std::move(cb); volumeCbs[addr] = std::move(cb); rusty::avrcp_device_connected(addr, /*absolute_volume_enabled=*/true); } void DeviceDisconnected(const RawAddress& addr) override { volumeCb.Reset(); volumeCbs.erase(addr); rusty::avrcp_device_disconnected(addr); } Loading @@ -175,16 +176,19 @@ public: } // Set CT's (headsets, speakers) volume. void SetDeviceVolume(int8_t volume) { if (!volumeCb || volume < 0) { void SetDeviceVolume(const RawAddress& addr, int8_t volume) { if (volume < 0) { return; } volumeCb.Run(volume); const auto& cb_iter = this->volumeCbs.find(addr); if (cb_iter != this->volumeCbs.end()) { cb_iter->second.Run(volume); } } private: VolumeInterface::VolumeChangedCb volumeCb; std::map<RawAddress, VolumeInterface::VolumeChangedCb> volumeCbs; }; } // namespace bluetooth::avrcp Loading Loading @@ -362,7 +366,9 @@ void AvrcpIntf::cleanup() { intf_->Cleanup(); } uint32_t AvrcpIntf::connect(RawAddress addr) { return intf_->ConnectDevice(addr); } uint32_t AvrcpIntf::disconnect(RawAddress addr) { return intf_->DisconnectDevice(addr); } void AvrcpIntf::set_volume(int8_t volume) { return mVolumeInterface.SetDeviceVolume(volume); } void AvrcpIntf::set_volume(RawAddress addr, int8_t volume) { return mVolumeInterface.SetDeviceVolume(addr, volume); } void AvrcpIntf::set_playback_status(const ::rust::String& status) { avrcp::PlayState state = avrcp::PlayState::STOPPED; Loading system/gd/rust/topshim/btav/btav_shim.h +1 −1 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ public: uint32_t disconnect(RawAddress addr); // interface for Audio server void set_volume(int8_t volume); void set_volume(RawAddress addr, int8_t volume); void set_playback_status(const ::rust::String& status); void set_position(int64_t position_us); Loading system/gd/rust/topshim/src/profiles/avrcp.rs +3 −3 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ pub mod ffi { fn cleanup(self: Pin<&mut AvrcpIntf>); fn connect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u32; fn disconnect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u32; fn set_volume(self: Pin<&mut AvrcpIntf>, volume: i8); fn set_volume(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress, volume: i8); fn set_playback_status(self: Pin<&mut AvrcpIntf>, status: &String); fn set_position(self: Pin<&mut AvrcpIntf>, position_us: i64); fn set_metadata( Loading Loading @@ -173,8 +173,8 @@ impl Avrcp { } #[profile_enabled_or] pub fn set_volume(&mut self, volume: i8) { self.internal.pin_mut().set_volume(volume); pub fn set_volume(&mut self, addr: RawAddress, volume: i8) { self.internal.pin_mut().set_volume(addr, volume); } #[profile_enabled_or(false)] Loading Loading
system/gd/rust/linux/stack/src/bluetooth_media.rs +55 −39 Original line number Diff line number Diff line //! Anything related to audio and media API. use bt_topshim::btif::{ BluetoothInterface, BtBondState, BtConnectionDirection, BtStatus, BtTransport, DisplayAddress, RawAddress, ToggleableProfile, BluetoothInterface, BtBondState, BtStatus, BtTransport, DisplayAddress, RawAddress, ToggleableProfile, }; use bt_topshim::profiles::a2dp::{ A2dp, A2dpCallbacks, A2dpCallbacksDispatcher, A2dpCodecBitsPerSample, A2dpCodecChannelMode, Loading Loading @@ -472,7 +472,8 @@ pub struct BluetoothMedia { adapter: Arc<Mutex<Box<Bluetooth>>>, a2dp: A2dp, avrcp: Avrcp, avrcp_direction: BtConnectionDirection, avrcp_address: Option<RawAddress>, avrcp_states: HashMap<RawAddress, BtavConnectionState>, a2dp_states: HashMap<RawAddress, BtavConnectionState>, a2dp_audio_state: HashMap<RawAddress, BtavAudioState>, a2dp_has_interrupted_stream: bool, // Only used for qualification. Loading Loading @@ -548,7 +549,8 @@ impl BluetoothMedia { adapter, a2dp, avrcp, avrcp_direction: BtConnectionDirection::Unknown, avrcp_address: None, avrcp_states: HashMap::new(), a2dp_states: HashMap::new(), a2dp_audio_state: HashMap::new(), a2dp_has_interrupted_stream: false, Loading Loading @@ -1307,6 +1309,31 @@ impl BluetoothMedia { supported ); // If is device initiated the AVRCP connection, emit a fake connecting state as // stack don't receive one. if self.avrcp_states.get(&addr) != Some(&BtavConnectionState::Connecting) { metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Connecting as u32, ); } metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Connected as u32, ); self.avrcp_states.insert(addr, BtavConnectionState::Connected); if self.avrcp_address.is_some() { warn!("Another AVRCP connection exists. Disconnect {}", DisplayAddress(&addr)); self.avrcp.disconnect(addr); return; } self.avrcp_address = Some(addr); match self.uinput.create(self.adapter_get_remote_name(addr), addr.to_string()) { Ok(()) => info!("uinput device created for: {}", DisplayAddress(&addr)), Err(e) => warn!("{}", e), Loading @@ -1325,30 +1352,34 @@ impl BluetoothMedia { } self.absolute_volume = supported; self.add_connected_profile(addr, Profile::AvrcpController); } AvrcpCallbacks::AvrcpDeviceDisconnected(addr) => { info!("[{}]: avrcp disconnected.", DisplayAddress(&addr)); // If is device initiated the AVRCP connection, emit a fake connecting state as // stack don't receive one. if self.avrcp_direction != BtConnectionDirection::Outgoing { // If the peer device initiated the AVRCP disconnection, emit a fake connecting // state as stack don't receive one. if self.avrcp_states.get(&addr) != Some(&BtavConnectionState::Disconnecting) { metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Connecting as u32, BtavConnectionState::Disconnecting as u32, ); } metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Connected as u32, BtavConnectionState::Disconnected as u32, ); // Reset direction to unknown. self.avrcp_direction = BtConnectionDirection::Unknown; self.avrcp_states.remove(&addr); self.add_connected_profile(addr, Profile::AvrcpController); if self.avrcp_address != Some(addr) { // Ignore disconnection to address we don't care return; } AvrcpCallbacks::AvrcpDeviceDisconnected(addr) => { info!("[{}]: avrcp disconnected.", DisplayAddress(&addr)); self.avrcp_address = None; self.uinput.close(addr.to_string()); Loading @@ -1362,25 +1393,6 @@ impl BluetoothMedia { None => false, }; // If the peer device initiated the AVRCP disconnection, emit a fake connecting // state as stack don't receive one. if self.avrcp_direction != BtConnectionDirection::Outgoing { metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Disconnecting as u32, ); } metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, BtStatus::Success, BtavConnectionState::Disconnected as u32, ); // Reset direction to unknown. self.avrcp_direction = BtConnectionDirection::Unknown; self.rm_connected_profile(addr, Profile::AvrcpController, is_profile_critical); } AvrcpCallbacks::AvrcpAbsoluteVolumeUpdate(volume) => { Loading Loading @@ -3336,11 +3348,11 @@ impl IBluetoothMedia for BluetoothMedia { BtStatus::Success, BtavConnectionState::Connecting as u32, ); self.avrcp_direction = BtConnectionDirection::Outgoing; self.avrcp_states.insert(addr, BtavConnectionState::Connecting); let status = self.avrcp.connect(addr); if BtStatus::Success != status { // Reset direction to unknown. self.avrcp_direction = BtConnectionDirection::Unknown; self.avrcp_states.remove(&addr); metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, Loading Loading @@ -3463,11 +3475,11 @@ impl IBluetoothMedia for BluetoothMedia { BtStatus::Success, BtavConnectionState::Disconnecting as u32, ); self.avrcp_direction = BtConnectionDirection::Outgoing; self.avrcp_states.insert(addr, BtavConnectionState::Disconnecting); let status = self.avrcp.disconnect(addr); if BtStatus::Success != status { // Reset direction to unknown. self.avrcp_direction = BtConnectionDirection::Unknown; self.avrcp_states.remove(&addr); metrics::profile_connection_state_changed( addr, Profile::AvrcpController as u32, Loading Loading @@ -3569,6 +3581,10 @@ impl IBluetoothMedia for BluetoothMedia { } fn set_volume(&mut self, volume: u8) { if self.avrcp_address.is_none() { return; } // Guard the range 0-127 by the try_from cast from u8 to i8. let vol = match i8::try_from(volume) { Ok(val) => val, Loading @@ -3578,7 +3594,7 @@ impl IBluetoothMedia for BluetoothMedia { } }; self.avrcp.set_volume(vol); self.avrcp.set_volume(self.avrcp_address.unwrap(), vol); } fn set_hfp_volume(&mut self, volume: u8, addr: RawAddress) { Loading
system/gd/rust/topshim/btav/btav_shim.cc +13 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "rust/topshim/btav/btav_shim.h" #include <cstdio> #include <map> #include <memory> #include "base/functional/callback.h" Loading Loading @@ -156,12 +157,12 @@ public: } void DeviceConnected(const RawAddress& addr, VolumeChangedCb cb) override { volumeCb = std::move(cb); volumeCbs[addr] = std::move(cb); rusty::avrcp_device_connected(addr, /*absolute_volume_enabled=*/true); } void DeviceDisconnected(const RawAddress& addr) override { volumeCb.Reset(); volumeCbs.erase(addr); rusty::avrcp_device_disconnected(addr); } Loading @@ -175,16 +176,19 @@ public: } // Set CT's (headsets, speakers) volume. void SetDeviceVolume(int8_t volume) { if (!volumeCb || volume < 0) { void SetDeviceVolume(const RawAddress& addr, int8_t volume) { if (volume < 0) { return; } volumeCb.Run(volume); const auto& cb_iter = this->volumeCbs.find(addr); if (cb_iter != this->volumeCbs.end()) { cb_iter->second.Run(volume); } } private: VolumeInterface::VolumeChangedCb volumeCb; std::map<RawAddress, VolumeInterface::VolumeChangedCb> volumeCbs; }; } // namespace bluetooth::avrcp Loading Loading @@ -362,7 +366,9 @@ void AvrcpIntf::cleanup() { intf_->Cleanup(); } uint32_t AvrcpIntf::connect(RawAddress addr) { return intf_->ConnectDevice(addr); } uint32_t AvrcpIntf::disconnect(RawAddress addr) { return intf_->DisconnectDevice(addr); } void AvrcpIntf::set_volume(int8_t volume) { return mVolumeInterface.SetDeviceVolume(volume); } void AvrcpIntf::set_volume(RawAddress addr, int8_t volume) { return mVolumeInterface.SetDeviceVolume(addr, volume); } void AvrcpIntf::set_playback_status(const ::rust::String& status) { avrcp::PlayState state = avrcp::PlayState::STOPPED; Loading
system/gd/rust/topshim/btav/btav_shim.h +1 −1 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ public: uint32_t disconnect(RawAddress addr); // interface for Audio server void set_volume(int8_t volume); void set_volume(RawAddress addr, int8_t volume); void set_playback_status(const ::rust::String& status); void set_position(int64_t position_us); Loading
system/gd/rust/topshim/src/profiles/avrcp.rs +3 −3 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ pub mod ffi { fn cleanup(self: Pin<&mut AvrcpIntf>); fn connect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u32; fn disconnect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u32; fn set_volume(self: Pin<&mut AvrcpIntf>, volume: i8); fn set_volume(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress, volume: i8); fn set_playback_status(self: Pin<&mut AvrcpIntf>, status: &String); fn set_position(self: Pin<&mut AvrcpIntf>, position_us: i64); fn set_metadata( Loading Loading @@ -173,8 +173,8 @@ impl Avrcp { } #[profile_enabled_or] pub fn set_volume(&mut self, volume: i8) { self.internal.pin_mut().set_volume(volume); pub fn set_volume(&mut self, addr: RawAddress, volume: i8) { self.internal.pin_mut().set_volume(addr, volume); } #[profile_enabled_or(false)] Loading