Loading system/gd/rust/linux/stack/src/bluetooth_media.rs +71 −20 Original line number Diff line number Diff line Loading @@ -472,7 +472,6 @@ pub struct BluetoothMedia { adapter: Arc<Mutex<Box<Bluetooth>>>, a2dp: A2dp, avrcp: Avrcp, avrcp_address: Option<RawAddress>, avrcp_states: HashMap<RawAddress, BtavConnectionState>, a2dp_states: HashMap<RawAddress, BtavConnectionState>, a2dp_audio_state: HashMap<RawAddress, BtavAudioState>, Loading Loading @@ -549,7 +548,6 @@ impl BluetoothMedia { adapter, a2dp, avrcp, avrcp_address: None, avrcp_states: HashMap::new(), a2dp_states: HashMap::new(), a2dp_audio_state: HashMap::new(), Loading Loading @@ -637,7 +635,13 @@ impl BluetoothMedia { return; } self.connected_profiles.entry(addr).or_default().remove(&profile); if let Some(profiles) = self.connected_profiles.get_mut(&addr) { profiles.remove(&profile); if profiles.is_empty() { self.connected_profiles.remove(&addr); } } self.delay_volume_update.remove(&profile); if is_profile_critical && self.is_complete_profiles_required() { Loading Loading @@ -1247,12 +1251,31 @@ impl BluetoothMedia { BtavConnectionState::Connected => { info!("[{}]: a2dp connected.", DisplayAddress(&addr)); if !self.connected_profiles.is_empty() && !self.connected_profiles.contains_key(&addr) { warn!( "Another media connection exists. Disconnect a2dp from {}", DisplayAddress(&addr) ); self.a2dp.disconnect(addr); return; } self.a2dp_states.insert(addr, state); self.add_connected_profile(addr, Profile::A2dpSink); } BtavConnectionState::Disconnected => { info!("[{}]: a2dp disconnected.", DisplayAddress(&addr)); if !self.connected_profiles.contains_key(&addr) { warn!( "Ignoring non-primary a2dp disconnection from {}", DisplayAddress(&addr) ); return; } if self.a2dp_audio_connection_listener.is_some() { let listener = self.a2dp_audio_connection_listener.take().unwrap(); let data: Vec<u8> = vec![0]; Loading Loading @@ -1325,14 +1348,19 @@ impl BluetoothMedia { 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)); if !self.connected_profiles.is_empty() && !self.connected_profiles.contains_key(&addr) { warn!( "Another media connection exists. Disconnect avrcp from {}", DisplayAddress(&addr) ); self.avrcp.disconnect(addr); return; } self.avrcp_address = Some(addr); self.avrcp_states.insert(addr, BtavConnectionState::Connected); match self.uinput.create(self.adapter_get_remote_name(addr), addr.to_string()) { Ok(()) => info!("uinput device created for: {}", DisplayAddress(&addr)), Loading Loading @@ -1373,13 +1401,15 @@ impl BluetoothMedia { BtStatus::Success, BtavConnectionState::Disconnected as u32, ); self.avrcp_states.remove(&addr); if self.avrcp_address != Some(addr) { // Ignore disconnection to address we don't care if !self.connected_profiles.contains_key(&addr) { warn!( "Ignoring non-primary avrcp disconnection from {}", DisplayAddress(&addr) ); return; } self.avrcp_address = None; self.avrcp_states.remove(&addr); self.uinput.close(addr.to_string()); Loading Loading @@ -1481,6 +1511,18 @@ impl BluetoothMedia { } BthfConnectionState::SlcConnected => { info!("[{}]: hfp slc connected.", DisplayAddress(&addr)); if !self.connected_profiles.is_empty() && !self.connected_profiles.contains_key(&addr) { warn!( "Another media connection exists. Disconnect hfp from {}", DisplayAddress(&addr) ); self.hfp.disconnect(addr); return; } // The device may not support codec-negotiation, // in which case we shall assume it supports CVSD at this point. self.hfp_cap.entry(addr).or_insert(HfpCodecFormat::CVSD); Loading @@ -1500,6 +1542,14 @@ impl BluetoothMedia { BthfConnectionState::Disconnected => { info!("[{}]: hfp disconnected.", DisplayAddress(&addr)); if !self.connected_profiles.contains_key(&addr) { warn!( "Ignoring non-primary hfp disconnection from {}", DisplayAddress(&addr) ); return; } if self.hfp_audio_connection_listener.is_some() { let listener = self.hfp_audio_connection_listener.take().unwrap(); let data: Vec<u8> = vec![0]; Loading Loading @@ -2271,7 +2321,7 @@ impl BluetoothMedia { let mut states = self.device_states.lock().unwrap(); let mut first_conn_ts = Instant::now(); let is_profile_cleared = self.connected_profiles.get(&addr).unwrap().is_empty(); let is_profile_cleared = !self.connected_profiles.contains_key(&addr); if let Some(task) = guard.get(&addr) { if let Some((handler, ts)) = task { Loading Loading @@ -2315,7 +2365,6 @@ impl BluetoothMedia { // Cleanup if transitioning to empty set. if is_profile_cleared { info!("[{}]: Device connection state: Disconnected.", DisplayAddress(&addr)); self.connected_profiles.remove(&addr); states.remove(&addr); guard.remove(&addr); let tx = self.tx.clone(); Loading Loading @@ -3282,11 +3331,11 @@ impl IBluetoothMedia for BluetoothMedia { available_profiles ); let connected_profiles = self.connected_profiles.entry(addr).or_default(); let connected_profiles = self.connected_profiles.get(&addr).cloned().unwrap_or_default(); // Sort here so the order of connection is always consistent let missing_profiles = available_profiles.difference(connected_profiles).sorted().collect::<Vec<_>>(); available_profiles.difference(&connected_profiles).sorted().collect::<Vec<_>>(); // Connect the profiles one-by-one so it won't stuck at the lower layer. // Therefore, just connect to one profile for now. Loading Loading @@ -3581,10 +3630,6 @@ 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 @@ -3594,7 +3639,13 @@ impl IBluetoothMedia for BluetoothMedia { } }; self.avrcp.set_volume(self.avrcp_address.unwrap(), vol); // There is always no more than one active media connection, which // implies only one address is connected with AVRCP. for (addr, profiles) in &self.connected_profiles { if profiles.contains(&Profile::AvrcpController) { self.avrcp.set_volume(*addr, vol); } } } fn set_hfp_volume(&mut self, volume: u8, addr: RawAddress) { Loading Loading
system/gd/rust/linux/stack/src/bluetooth_media.rs +71 −20 Original line number Diff line number Diff line Loading @@ -472,7 +472,6 @@ pub struct BluetoothMedia { adapter: Arc<Mutex<Box<Bluetooth>>>, a2dp: A2dp, avrcp: Avrcp, avrcp_address: Option<RawAddress>, avrcp_states: HashMap<RawAddress, BtavConnectionState>, a2dp_states: HashMap<RawAddress, BtavConnectionState>, a2dp_audio_state: HashMap<RawAddress, BtavAudioState>, Loading Loading @@ -549,7 +548,6 @@ impl BluetoothMedia { adapter, a2dp, avrcp, avrcp_address: None, avrcp_states: HashMap::new(), a2dp_states: HashMap::new(), a2dp_audio_state: HashMap::new(), Loading Loading @@ -637,7 +635,13 @@ impl BluetoothMedia { return; } self.connected_profiles.entry(addr).or_default().remove(&profile); if let Some(profiles) = self.connected_profiles.get_mut(&addr) { profiles.remove(&profile); if profiles.is_empty() { self.connected_profiles.remove(&addr); } } self.delay_volume_update.remove(&profile); if is_profile_critical && self.is_complete_profiles_required() { Loading Loading @@ -1247,12 +1251,31 @@ impl BluetoothMedia { BtavConnectionState::Connected => { info!("[{}]: a2dp connected.", DisplayAddress(&addr)); if !self.connected_profiles.is_empty() && !self.connected_profiles.contains_key(&addr) { warn!( "Another media connection exists. Disconnect a2dp from {}", DisplayAddress(&addr) ); self.a2dp.disconnect(addr); return; } self.a2dp_states.insert(addr, state); self.add_connected_profile(addr, Profile::A2dpSink); } BtavConnectionState::Disconnected => { info!("[{}]: a2dp disconnected.", DisplayAddress(&addr)); if !self.connected_profiles.contains_key(&addr) { warn!( "Ignoring non-primary a2dp disconnection from {}", DisplayAddress(&addr) ); return; } if self.a2dp_audio_connection_listener.is_some() { let listener = self.a2dp_audio_connection_listener.take().unwrap(); let data: Vec<u8> = vec![0]; Loading Loading @@ -1325,14 +1348,19 @@ impl BluetoothMedia { 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)); if !self.connected_profiles.is_empty() && !self.connected_profiles.contains_key(&addr) { warn!( "Another media connection exists. Disconnect avrcp from {}", DisplayAddress(&addr) ); self.avrcp.disconnect(addr); return; } self.avrcp_address = Some(addr); self.avrcp_states.insert(addr, BtavConnectionState::Connected); match self.uinput.create(self.adapter_get_remote_name(addr), addr.to_string()) { Ok(()) => info!("uinput device created for: {}", DisplayAddress(&addr)), Loading Loading @@ -1373,13 +1401,15 @@ impl BluetoothMedia { BtStatus::Success, BtavConnectionState::Disconnected as u32, ); self.avrcp_states.remove(&addr); if self.avrcp_address != Some(addr) { // Ignore disconnection to address we don't care if !self.connected_profiles.contains_key(&addr) { warn!( "Ignoring non-primary avrcp disconnection from {}", DisplayAddress(&addr) ); return; } self.avrcp_address = None; self.avrcp_states.remove(&addr); self.uinput.close(addr.to_string()); Loading Loading @@ -1481,6 +1511,18 @@ impl BluetoothMedia { } BthfConnectionState::SlcConnected => { info!("[{}]: hfp slc connected.", DisplayAddress(&addr)); if !self.connected_profiles.is_empty() && !self.connected_profiles.contains_key(&addr) { warn!( "Another media connection exists. Disconnect hfp from {}", DisplayAddress(&addr) ); self.hfp.disconnect(addr); return; } // The device may not support codec-negotiation, // in which case we shall assume it supports CVSD at this point. self.hfp_cap.entry(addr).or_insert(HfpCodecFormat::CVSD); Loading @@ -1500,6 +1542,14 @@ impl BluetoothMedia { BthfConnectionState::Disconnected => { info!("[{}]: hfp disconnected.", DisplayAddress(&addr)); if !self.connected_profiles.contains_key(&addr) { warn!( "Ignoring non-primary hfp disconnection from {}", DisplayAddress(&addr) ); return; } if self.hfp_audio_connection_listener.is_some() { let listener = self.hfp_audio_connection_listener.take().unwrap(); let data: Vec<u8> = vec![0]; Loading Loading @@ -2271,7 +2321,7 @@ impl BluetoothMedia { let mut states = self.device_states.lock().unwrap(); let mut first_conn_ts = Instant::now(); let is_profile_cleared = self.connected_profiles.get(&addr).unwrap().is_empty(); let is_profile_cleared = !self.connected_profiles.contains_key(&addr); if let Some(task) = guard.get(&addr) { if let Some((handler, ts)) = task { Loading Loading @@ -2315,7 +2365,6 @@ impl BluetoothMedia { // Cleanup if transitioning to empty set. if is_profile_cleared { info!("[{}]: Device connection state: Disconnected.", DisplayAddress(&addr)); self.connected_profiles.remove(&addr); states.remove(&addr); guard.remove(&addr); let tx = self.tx.clone(); Loading Loading @@ -3282,11 +3331,11 @@ impl IBluetoothMedia for BluetoothMedia { available_profiles ); let connected_profiles = self.connected_profiles.entry(addr).or_default(); let connected_profiles = self.connected_profiles.get(&addr).cloned().unwrap_or_default(); // Sort here so the order of connection is always consistent let missing_profiles = available_profiles.difference(connected_profiles).sorted().collect::<Vec<_>>(); available_profiles.difference(&connected_profiles).sorted().collect::<Vec<_>>(); // Connect the profiles one-by-one so it won't stuck at the lower layer. // Therefore, just connect to one profile for now. Loading Loading @@ -3581,10 +3630,6 @@ 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 @@ -3594,7 +3639,13 @@ impl IBluetoothMedia for BluetoothMedia { } }; self.avrcp.set_volume(self.avrcp_address.unwrap(), vol); // There is always no more than one active media connection, which // implies only one address is connected with AVRCP. for (addr, profiles) in &self.connected_profiles { if profiles.contains(&Profile::AvrcpController) { self.avrcp.set_volume(*addr, vol); } } } fn set_hfp_volume(&mut self, volume: u8, addr: RawAddress) { Loading