Loading system/gd/rust/linux/stack/src/bluetooth_media.rs +81 −147 Original line number Diff line number Diff line Loading @@ -14,9 +14,9 @@ use bt_topshim::profiles::avrcp::{ }; use bt_topshim::profiles::hfp::interop_insert_call_when_sco_start; use bt_topshim::profiles::hfp::{ BthfAudioState, BthfConnectionState, CallHoldCommand, CallInfo, CallSource, CallState, EscoCodingFormat, Hfp, HfpCallbacks, HfpCallbacksDispatcher, HfpCodecBitId, HfpCodecFormat, HfpCodecId, PhoneState, TelephonyDeviceStatus, BthfAudioState, BthfConnectionState, CallHoldCommand, CallInfo, CallState, EscoCodingFormat, Hfp, HfpCallbacks, HfpCallbacksDispatcher, HfpCodecBitId, HfpCodecFormat, HfpCodecId, PhoneState, TelephonyDeviceStatus, }; use bt_topshim::profiles::ProfileConnectionState; use bt_topshim::{metrics, topstack}; Loading Loading @@ -722,8 +722,15 @@ impl BluetoothMedia { self.start_sco_call_impl(addr.to_string(), false, HfpCodecBitId::NONE); } if self.should_insert_call_when_sco_start(addr) { info!( "[{}]: UHID creation skipped due to interop workaround", DisplayAddress(&addr) ); } else { self.uhid_create(addr); } } BthfConnectionState::Disconnected => { info!("[{}]: hfp disconnected.", DisplayAddress(&addr)); self.uhid_destroy(&addr); Loading Loading @@ -756,16 +763,13 @@ impl BluetoothMedia { self.hfp_audio_state.insert(addr, state); if self.should_insert_call_when_sco_start(addr) && self.call_list.iter().all(|c| c.source != CallSource::CRAS) { if self.should_insert_call_when_sco_start(addr) { // This triggers a +CIEV command to set the call status for HFP devices. // It is required for some devices to provide sound. self.phone_state.num_active += 1; self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: false, source: CallSource::CRAS, state: CallState::Active, number: "".into(), }); Loading @@ -784,19 +788,10 @@ impl BluetoothMedia { }); } if !self.mps_qualification_enabled && self.call_list.iter().any(|c| c.source == CallSource::CRAS) { for c in self.call_list.iter_mut() { if c.source == CallSource::CRAS { self.phone_state.num_active -= 1; } } self.call_list.retain(|x| match x.source { CallSource::CRAS => false, _ => true, }); if self.should_insert_call_when_sco_start(addr) { // Remove the only call related to the one added for devices requesting to force +CIEV command self.call_list = vec![]; self.phone_state.num_active = 0; self.phone_state_change("".into()); } Loading Loading @@ -1018,6 +1013,15 @@ impl BluetoothMedia { self.uhid_send_input_report(&addr); } HfpCallbacks::HangupCall(addr) => { if self.should_insert_call_when_sco_start(addr) { // The devices requiring a +CIEV event are not managed through the telephony commands. // This allows to prevent to stop the SCO link as there is no command to set it up again. debug!( "[{}]: AT+CHUP skipped due to interop workaround", DisplayAddress(&addr) ); return; } if !self.hangup_call_impl() { warn!("[{}]: hangup_call triggered by AT+CHUP failed", DisplayAddress(&addr)); return; Loading Loading @@ -1213,7 +1217,7 @@ impl BluetoothMedia { } if let Some(uhid) = self.uhid.get_mut(addr) { let mut data = 0; if self.call_list.iter().any(|c| c.source == CallSource::HID) { if self.phone_state.num_active > 0 { data |= UHID_INPUT_HOOK_SWITCH; } if uhid.muted { Loading Loading @@ -1926,7 +1930,10 @@ impl BluetoothMedia { } fn answer_call_impl(&mut self) -> bool { if self.mps_qualification_enabled { if !self.phone_ops_enabled && !self.mps_qualification_enabled { return false; } if self.phone_state.state == CallState::Idle { return false; } Loading @@ -1942,34 +1949,15 @@ impl BluetoothMedia { } self.phone_state.state = CallState::Idle; self.phone_state.num_active += 1; return true; } else if self.phone_ops_enabled { if self.phone_state.state == CallState::Idle { return false; } // There must be exactly one incoming/dialing call in the list. for c in self.call_list.iter_mut() { if c.source == CallSource::CRAS { continue; } match c.state { CallState::Incoming | CallState::Dialing | CallState::Alerting => { c.state = CallState::Active; self.phone_state.state = CallState::Idle; self.phone_state.num_active += 1; return true; } _ => {} } } true } fn hangup_call_impl(&mut self) -> bool { if !self.phone_ops_enabled && !self.mps_qualification_enabled { return false; } fn hangup_call_impl(&mut self) -> bool { if self.mps_qualification_enabled { match self.phone_state.state { CallState::Idle if self.phone_state.num_active > 0 => { self.phone_state.num_active -= 1; Loading @@ -1982,41 +1970,13 @@ impl BluetoothMedia { // At this point, there must be exactly one incoming/dialing/alerting/active call to be // removed. self.call_list.retain(|x| match x.state { CallState::Active | CallState::Incoming | CallState::Dialing | CallState::Alerting => false, _ => true, }); return true; } else if self.phone_ops_enabled { let mut ret = false; for c in self.call_list.iter_mut() { if c.source == CallSource::CRAS { continue; } match c.state { CallState::Incoming | CallState::Dialing | CallState::Alerting => { ret = true; } CallState::Active => { self.phone_state.num_active -= 1; ret = true; } _ => {} } CallState::Active | CallState::Incoming | CallState::Dialing | CallState::Alerting => { false } self.call_list.retain(|x| match x.source { CallSource::HID => false, _ => true, }); self.phone_state.state = CallState::Idle; return ret; } return false; true } fn dialing_call_impl(&mut self, number: String) -> bool { Loading @@ -2025,29 +1985,17 @@ impl BluetoothMedia { { return false; } if self.mps_qualification_enabled { if self.phone_state.num_active > 0 { return false; } self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: false, source: CallSource::CRAS, state: CallState::Dialing, number: number.clone(), }); } else if self.phone_ops_enabled { if self.call_list.iter().any(|c| c.source == CallSource::HID) { return false; } self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: false, source: CallSource::HID, state: CallState::Dialing, number: number.clone(), }); } self.phone_state.state = CallState::Dialing; true } Loading Loading @@ -2958,7 +2906,6 @@ impl IBluetoothTelephony for BluetoothMedia { self.call_list.push(CallInfo { index: 1, dir_incoming: false, source: CallSource::CRAS, state: CallState::Active, number: "".into(), }); Loading Loading @@ -2989,7 +2936,6 @@ impl IBluetoothTelephony for BluetoothMedia { self.call_list.push(CallInfo { index: 1, dir_incoming: false, source: CallSource::CRAS, state: CallState::Active, number: "".into(), }); Loading @@ -3005,29 +2951,17 @@ impl IBluetoothTelephony for BluetoothMedia { { return false; } if self.mps_qualification_enabled { if self.phone_state.num_active > 0 { return false; } self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: true, source: CallSource::CRAS, state: CallState::Incoming, number: number.clone(), }); } else if self.phone_ops_enabled { if self.call_list.iter().any(|c| c.source == CallSource::HID) { return false; } self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: true, source: CallSource::HID, state: CallState::Incoming, number: number.clone(), }); } self.phone_state.state = CallState::Incoming; self.phone_state_change(number); self.try_a2dp_suspend(); Loading system/gd/rust/topshim/src/profiles/hfp.rs +0 −15 Original line number Diff line number Diff line Loading @@ -159,24 +159,10 @@ pub mod ffi { Held, // Only used by CLCC response } #[derive(Debug, Copy, Clone)] /* When a SCO is created, it is necessary to have at least one call in the call list. Otherwise, some headsets may not be able to output sound. Therefore, we need to separate the call for CRAS from the call for the application so that we can have a correct life cycle for the call list status. */ pub enum CallSource { CRAS, HID, } #[derive(Debug, Clone)] pub struct CallInfo { index: i32, dir_incoming: bool, source: CallSource, state: CallState, number: String, } Loading Loading @@ -292,7 +278,6 @@ impl TelephonyDeviceStatus { } pub type CallState = ffi::CallState; pub type CallSource = ffi::CallSource; pub type CallInfo = ffi::CallInfo; pub type PhoneState = ffi::PhoneState; pub type CallHoldCommand = ffi::CallHoldCommand; Loading Loading
system/gd/rust/linux/stack/src/bluetooth_media.rs +81 −147 Original line number Diff line number Diff line Loading @@ -14,9 +14,9 @@ use bt_topshim::profiles::avrcp::{ }; use bt_topshim::profiles::hfp::interop_insert_call_when_sco_start; use bt_topshim::profiles::hfp::{ BthfAudioState, BthfConnectionState, CallHoldCommand, CallInfo, CallSource, CallState, EscoCodingFormat, Hfp, HfpCallbacks, HfpCallbacksDispatcher, HfpCodecBitId, HfpCodecFormat, HfpCodecId, PhoneState, TelephonyDeviceStatus, BthfAudioState, BthfConnectionState, CallHoldCommand, CallInfo, CallState, EscoCodingFormat, Hfp, HfpCallbacks, HfpCallbacksDispatcher, HfpCodecBitId, HfpCodecFormat, HfpCodecId, PhoneState, TelephonyDeviceStatus, }; use bt_topshim::profiles::ProfileConnectionState; use bt_topshim::{metrics, topstack}; Loading Loading @@ -722,8 +722,15 @@ impl BluetoothMedia { self.start_sco_call_impl(addr.to_string(), false, HfpCodecBitId::NONE); } if self.should_insert_call_when_sco_start(addr) { info!( "[{}]: UHID creation skipped due to interop workaround", DisplayAddress(&addr) ); } else { self.uhid_create(addr); } } BthfConnectionState::Disconnected => { info!("[{}]: hfp disconnected.", DisplayAddress(&addr)); self.uhid_destroy(&addr); Loading Loading @@ -756,16 +763,13 @@ impl BluetoothMedia { self.hfp_audio_state.insert(addr, state); if self.should_insert_call_when_sco_start(addr) && self.call_list.iter().all(|c| c.source != CallSource::CRAS) { if self.should_insert_call_when_sco_start(addr) { // This triggers a +CIEV command to set the call status for HFP devices. // It is required for some devices to provide sound. self.phone_state.num_active += 1; self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: false, source: CallSource::CRAS, state: CallState::Active, number: "".into(), }); Loading @@ -784,19 +788,10 @@ impl BluetoothMedia { }); } if !self.mps_qualification_enabled && self.call_list.iter().any(|c| c.source == CallSource::CRAS) { for c in self.call_list.iter_mut() { if c.source == CallSource::CRAS { self.phone_state.num_active -= 1; } } self.call_list.retain(|x| match x.source { CallSource::CRAS => false, _ => true, }); if self.should_insert_call_when_sco_start(addr) { // Remove the only call related to the one added for devices requesting to force +CIEV command self.call_list = vec![]; self.phone_state.num_active = 0; self.phone_state_change("".into()); } Loading Loading @@ -1018,6 +1013,15 @@ impl BluetoothMedia { self.uhid_send_input_report(&addr); } HfpCallbacks::HangupCall(addr) => { if self.should_insert_call_when_sco_start(addr) { // The devices requiring a +CIEV event are not managed through the telephony commands. // This allows to prevent to stop the SCO link as there is no command to set it up again. debug!( "[{}]: AT+CHUP skipped due to interop workaround", DisplayAddress(&addr) ); return; } if !self.hangup_call_impl() { warn!("[{}]: hangup_call triggered by AT+CHUP failed", DisplayAddress(&addr)); return; Loading Loading @@ -1213,7 +1217,7 @@ impl BluetoothMedia { } if let Some(uhid) = self.uhid.get_mut(addr) { let mut data = 0; if self.call_list.iter().any(|c| c.source == CallSource::HID) { if self.phone_state.num_active > 0 { data |= UHID_INPUT_HOOK_SWITCH; } if uhid.muted { Loading Loading @@ -1926,7 +1930,10 @@ impl BluetoothMedia { } fn answer_call_impl(&mut self) -> bool { if self.mps_qualification_enabled { if !self.phone_ops_enabled && !self.mps_qualification_enabled { return false; } if self.phone_state.state == CallState::Idle { return false; } Loading @@ -1942,34 +1949,15 @@ impl BluetoothMedia { } self.phone_state.state = CallState::Idle; self.phone_state.num_active += 1; return true; } else if self.phone_ops_enabled { if self.phone_state.state == CallState::Idle { return false; } // There must be exactly one incoming/dialing call in the list. for c in self.call_list.iter_mut() { if c.source == CallSource::CRAS { continue; } match c.state { CallState::Incoming | CallState::Dialing | CallState::Alerting => { c.state = CallState::Active; self.phone_state.state = CallState::Idle; self.phone_state.num_active += 1; return true; } _ => {} } } true } fn hangup_call_impl(&mut self) -> bool { if !self.phone_ops_enabled && !self.mps_qualification_enabled { return false; } fn hangup_call_impl(&mut self) -> bool { if self.mps_qualification_enabled { match self.phone_state.state { CallState::Idle if self.phone_state.num_active > 0 => { self.phone_state.num_active -= 1; Loading @@ -1982,41 +1970,13 @@ impl BluetoothMedia { // At this point, there must be exactly one incoming/dialing/alerting/active call to be // removed. self.call_list.retain(|x| match x.state { CallState::Active | CallState::Incoming | CallState::Dialing | CallState::Alerting => false, _ => true, }); return true; } else if self.phone_ops_enabled { let mut ret = false; for c in self.call_list.iter_mut() { if c.source == CallSource::CRAS { continue; } match c.state { CallState::Incoming | CallState::Dialing | CallState::Alerting => { ret = true; } CallState::Active => { self.phone_state.num_active -= 1; ret = true; } _ => {} } CallState::Active | CallState::Incoming | CallState::Dialing | CallState::Alerting => { false } self.call_list.retain(|x| match x.source { CallSource::HID => false, _ => true, }); self.phone_state.state = CallState::Idle; return ret; } return false; true } fn dialing_call_impl(&mut self, number: String) -> bool { Loading @@ -2025,29 +1985,17 @@ impl BluetoothMedia { { return false; } if self.mps_qualification_enabled { if self.phone_state.num_active > 0 { return false; } self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: false, source: CallSource::CRAS, state: CallState::Dialing, number: number.clone(), }); } else if self.phone_ops_enabled { if self.call_list.iter().any(|c| c.source == CallSource::HID) { return false; } self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: false, source: CallSource::HID, state: CallState::Dialing, number: number.clone(), }); } self.phone_state.state = CallState::Dialing; true } Loading Loading @@ -2958,7 +2906,6 @@ impl IBluetoothTelephony for BluetoothMedia { self.call_list.push(CallInfo { index: 1, dir_incoming: false, source: CallSource::CRAS, state: CallState::Active, number: "".into(), }); Loading Loading @@ -2989,7 +2936,6 @@ impl IBluetoothTelephony for BluetoothMedia { self.call_list.push(CallInfo { index: 1, dir_incoming: false, source: CallSource::CRAS, state: CallState::Active, number: "".into(), }); Loading @@ -3005,29 +2951,17 @@ impl IBluetoothTelephony for BluetoothMedia { { return false; } if self.mps_qualification_enabled { if self.phone_state.num_active > 0 { return false; } self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: true, source: CallSource::CRAS, state: CallState::Incoming, number: number.clone(), }); } else if self.phone_ops_enabled { if self.call_list.iter().any(|c| c.source == CallSource::HID) { return false; } self.call_list.push(CallInfo { index: self.new_call_index(), dir_incoming: true, source: CallSource::HID, state: CallState::Incoming, number: number.clone(), }); } self.phone_state.state = CallState::Incoming; self.phone_state_change(number); self.try_a2dp_suspend(); Loading
system/gd/rust/topshim/src/profiles/hfp.rs +0 −15 Original line number Diff line number Diff line Loading @@ -159,24 +159,10 @@ pub mod ffi { Held, // Only used by CLCC response } #[derive(Debug, Copy, Clone)] /* When a SCO is created, it is necessary to have at least one call in the call list. Otherwise, some headsets may not be able to output sound. Therefore, we need to separate the call for CRAS from the call for the application so that we can have a correct life cycle for the call list status. */ pub enum CallSource { CRAS, HID, } #[derive(Debug, Clone)] pub struct CallInfo { index: i32, dir_incoming: bool, source: CallSource, state: CallState, number: String, } Loading Loading @@ -292,7 +278,6 @@ impl TelephonyDeviceStatus { } pub type CallState = ffi::CallState; pub type CallSource = ffi::CallSource; pub type CallInfo = ffi::CallInfo; pub type PhoneState = ffi::PhoneState; pub type CallHoldCommand = ffi::CallHoldCommand; Loading