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

Commit 14088ffe authored by Frédéric Danis's avatar Frédéric Danis
Browse files

Floss: Remove CallSource from CallInfo

Since "Floss: add workaround entry to insert call when sco start"
(commit 9d9ab011) the CallSource in call list is no longer needed.
This commit removes it to make the code cleaner.

It also prevents the creation of the UHID device and SCO link
disconnection on AT+CHUP reception for the devices requesting a +CIEV
event to start the SCO link.

Bug: 328696624
Test: Conduct the following manual tests.
  pair supported Bluetooth Headset
  load https://google.github.io/libhidtelephony/ with Chrome
  click on "Start", select the headset then "Connect"
  "Inputs Reports" and "Output Reports" are correct
  "Hook Switch", "Off-Hook", "Ring" and "Mute" test cases are passed
  used https://online-voice-recorder.com during "Hook Switch" and
    "off-Hook" tests to check audio input
  Google Meet: headset is able to mute, un-mute and hang-up the call
Test: Conduct the following manual tests.
  pair unsupported Bluetooth Headset or add it to
    INTEROP_INSERT_CALL_WHEN_SCO_START in
    /var/lib/bluetooth/interop_database.conf.
  load https://google.github.io/libhidtelephony/ with Chrome
  click on "Start", the headset is not proposed
  Google Meet: headset is usable but not able to mute, un-mute or hang-up
    the call
Test: atest bluetooth_test_gd
Tag: #floss
Flag: EXEMPT, no behavior change on Android; Floss-only changes

Change-Id: If5ac3206cdca4607f62e636014729c1b9b6198a7
parent fff12f83
Loading
Loading
Loading
Loading
+81 −147
Original line number Diff line number Diff line
@@ -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};
@@ -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);
@@ -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(),
                            });
@@ -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());
                        }

@@ -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;
@@ -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 {
@@ -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;
        }
@@ -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;
@@ -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 {
@@ -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
    }
@@ -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(),
            });
@@ -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(),
            });
@@ -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();
+0 −15
Original line number Diff line number Diff line
@@ -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,
    }
@@ -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;