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

Commit 9d9ab011 authored by WhaleChang's avatar WhaleChang Committed by Whale Chang
Browse files

Floss: add workaround entry to insert call when sco start

Bluetooth headsets that require CIEV commands to provide sound when HFP SCO starts can cause problems when developing Bluetooth telephony features.

This is because the workaround requires inserting one call into the call list, which can make it difficult to maintain the correct call state.

This can lead to bugs such as users being unable to answer calls the second time they are called, or being unable to answer calls while other audio streams are playing.

To address this issue, we have added an entry in interop that allows us to only apply the workaround to headsets that require CIEV commands based on their address.

Bug: 310065944
Test: atest bluetooth_test_gd
Test: disable bluetooth telephony, make sure the call exist when sco
start
Test: enable mps qualification mode, make sure the no call exist when sco
start
Test: Conduct the following manual tests.
  enable bluetooth telephony
  add Jabra Evolve2 address into /var/lib/bluetooth/interop_database.conf
  check the log show
  2023-12-06T07:02:03.719513Z WARNING btadapterd[19584]: bt_device_interop:  device/src/interop.cc:1355 - interop_database_match_addr: Device xx:xx:xx:xx:5d:59 is a match for interop workaround INTEROP_INSERT_CALL_WHEN_SCO_START.

Test: Conduct the following manual tests.
  pair Bluetooth Headset
  login to "Dialpad" via https://dialpad.com/login
  add Headset to "Dialpad" call control by following step:
    Profile -> Preferences -> Hardware Settings -> Call controls
    -> Add Headset -> Select headset and click connect.
  call to "Dialpad" with phone
  check there is a incoming call
  answer call on headset
  end call on headset
  perform a second call to "Dialpad" with phone
  check there is a incoming call
  answer call on headset
  end call on headset

Flag: EXEMPT floss only change

Change-Id: Iea1029f618dcd1d204902cd72fcf234473b74144
parent f4209007
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -339,6 +339,10 @@ typedef enum {
  // both encryption complete and SMP key exchange completed.
  INTEROP_SUSPEND_ATT_TRAFFIC_DURING_PAIRING,

  // This triggers a +CIEV command to set the call status for HFP devices.
  // It is required for some devices to provide sound.
  INTEROP_INSERT_CALL_WHEN_SCO_START,

  END_OF_INTEROP_LIST
} interop_feature_t;

+1 −0
Original line number Diff line number Diff line
@@ -393,6 +393,7 @@ static const char* interop_feature_string_(const interop_feature_t feature) {
    CASE_RETURN_STR(INTEROP_HFP_1_9_ALLOWLIST);
    CASE_RETURN_STR(INTEROP_IGNORE_DISC_BEFORE_SIGNALLING_TIMEOUT);
    CASE_RETURN_STR(INTEROP_SUSPEND_ATT_TRAFFIC_DURING_PAIRING);
    CASE_RETURN_STR(INTEROP_INSERT_CALL_WHEN_SCO_START);
  }
  return UNKNOWN_INTEROP_FEATURE;
}
+28 −16
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ use bt_topshim::profiles::a2dp::{
use bt_topshim::profiles::avrcp::{
    Avrcp, AvrcpCallbacks, AvrcpCallbacksDispatcher, PlayerMetadata,
};
use bt_topshim::profiles::hfp::interop_insert_call_when_sco_start;
use bt_topshim::profiles::hfp::{
    BthfAudioState, BthfConnectionState, CallHoldCommand, CallInfo, CallSource, CallState, Hfp,
    HfpCallbacks, HfpCallbacksDispatcher, HfpCodecCapability, HfpCodecId, PhoneState,
@@ -759,7 +760,7 @@ impl BluetoothMedia {

                        self.hfp_audio_state.insert(addr, state);

                        if !self.mps_qualification_enabled
                        if self.should_insert_call_when_sco_start(addr)
                            && self.call_list.iter().all(|c| c.source != CallSource::CRAS)
                        {
                            // This triggers a +CIEV command to set the call status for HFP devices.
@@ -2167,6 +2168,16 @@ impl BluetoothMedia {
    pub fn add_player(&mut self, name: String, browsing_supported: bool) {
        self.avrcp.as_mut().unwrap().add_player(&name, browsing_supported);
    }

    fn should_insert_call_when_sco_start(&self, address: RawAddress) -> bool {
        if self.mps_qualification_enabled {
            return false;
        }
        if !self.phone_ops_enabled {
            return true;
        }
        return interop_insert_call_when_sco_start(address);
    }
}

fn get_a2dp_dispatcher(tx: Sender<Message>) -> A2dpCallbacksDispatcher {
@@ -2704,7 +2715,6 @@ impl IBluetoothMedia for BluetoothMedia {
            }
            Some(addr) => addr,
        };

        let vol = match i8::try_from(volume) {
            Ok(val) if val <= 15 => val,
            _ => {
@@ -2908,7 +2918,10 @@ impl IBluetoothTelephony for BluetoothMedia {
        self.last_dialing_number = None;
        self.a2dp_has_interrupted_stream = false;

        if self.hfp_audio_state.values().any(|x| x == &BthfAudioState::Connected) {
        self.phone_ops_enabled = enable;
        if self.hfp_audio_state.keys().any(|addr| self.should_insert_call_when_sco_start(*addr))
            && self.hfp_audio_state.values().any(|x| x == &BthfAudioState::Connected)
        {
            self.call_list.push(CallInfo {
                index: 1,
                dir_incoming: false,
@@ -2919,7 +2932,6 @@ impl IBluetoothTelephony for BluetoothMedia {
            self.phone_state.num_active = 1;
        }

        self.phone_ops_enabled = enable;
        self.phone_state_change("".into());
    }

@@ -2936,9 +2948,11 @@ impl IBluetoothTelephony for BluetoothMedia {
        self.memory_dialing_number = None;
        self.last_dialing_number = None;
        self.a2dp_has_interrupted_stream = false;
        self.mps_qualification_enabled = enable;

        if !enable {
            if self.hfp_audio_state.values().any(|x| x == &BthfAudioState::Connected) {
        if self.hfp_audio_state.keys().any(|addr| self.should_insert_call_when_sco_start(*addr))
            && self.hfp_audio_state.values().any(|x| x == &BthfAudioState::Connected)
        {
            self.call_list.push(CallInfo {
                index: 1,
                dir_incoming: false,
@@ -2948,9 +2962,7 @@ impl IBluetoothTelephony for BluetoothMedia {
            });
            self.phone_state.num_active = 1;
        }
        }

        self.mps_qualification_enabled = enable;
        self.phone_state_change("".into());
    }

+5 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "gd/rust/topshim/hfp/hfp_shim.h"

#include "btif/include/btif_hf.h"
#include "device/include/interop.h"
#include "gd/common/strings.h"
#include "gd/os/log.h"
#include "include/hardware/bt_hf.h"
@@ -438,6 +439,10 @@ std::unique_ptr<HfpIntf> GetHfpProfile(const unsigned char* btif) {
  return hfpif;
}

bool interop_insert_call_when_sco_start(RawAddress addr) {
  return interop_match_addr(interop_feature_t::INTEROP_INSERT_CALL_WHEN_SCO_START, &addr);
}

}  // namespace rust
}  // namespace topshim
}  // namespace bluetooth
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ class HfpIntf {
};

std::unique_ptr<HfpIntf> GetHfpProfile(const unsigned char* btif);
bool interop_insert_call_when_sco_start(RawAddress addr);

}  // namespace rust
}  // namespace topshim
Loading