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

Commit 011bdd34 authored by Frédéric Danis's avatar Frédéric Danis
Browse files

Floss: Add Three-way call support

When HFP audio path is connected (CRAS call) before an incoming call the
stack is in a multi-party state, while the headset has been informed that
this is not supported (Three-way flag in +BRSF event). In this case the
headset is only able to reject the incoming call.

Bug: 300409919
Test: Conduct the following manual tests.
  pair Bluetooth Headset
  load https://online-voice-recorder.com and start recording
  load https://google.git.io/libhidtelephoony/ with Chrome
  click on "Start", select the headset then "Connect"
  "Inputs Reports" and "Output Reports" are correct
  start "Hook Switch" test case
  no ringtone is heard in headset
  accept call from headset
  hang up call from headset
  "Hook Switch" test case is pass and recording audio continues
Test: atest bluetooth_test_gd
Change-Id: I9980ad57ec83696bb0df53a9ed861b52a1950246
parent 0a52cf7f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -166,8 +166,8 @@ static uint32_t get_hf_features() {
          DEFAULT_BTIF_HF_FEATURES);
  return hf_features;
#elif TARGET_FLOSS
  return BTA_AG_FEAT_ECS | BTA_AG_FEAT_CODEC | BTA_AG_FEAT_UNAT |
         BTA_AG_FEAT_HF_IND;
  return BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECS | BTA_AG_FEAT_CODEC |
         BTA_AG_FEAT_UNAT | BTA_AG_FEAT_HF_IND;
#else
  return DEFAULT_BTIF_HF_FEATURES;
#endif
+59 −30
Original line number Diff line number Diff line
@@ -1047,6 +1047,7 @@ impl BluetoothMedia {
                if success {
                    // Success means the call state has changed. Inform libbluetooth.
                    self.phone_state_change("".into());
                    self.uhid_send_input_report(&addr);
                } else {
                    warn!(
                        "[{}]: Unexpected or unsupported CHLD command {:?} from HF",
@@ -2003,25 +2004,38 @@ impl BluetoothMedia {
    }

    fn release_held_impl(&mut self) -> bool {
        if !(self.phone_ops_enabled || self.mps_qualification_enabled)
            || self.phone_state.state != CallState::Idle
        {
        if !(self.phone_ops_enabled || self.mps_qualification_enabled) {
            return false;
        }

        if self.mps_qualification_enabled {
            if self.phone_state.state != CallState::Idle {
                return false;
            }
            self.call_list.retain(|x| x.state != CallState::Held);
            self.phone_state.num_held = 0;
        } else if self.phone_ops_enabled {
            if self.phone_state.state == CallState::Incoming {
                self.call_list.retain(|x| x.state != CallState::Incoming);
                self.phone_state.state = CallState::Idle;
            } else {
                return false;
            }
        }
        true
    }

    fn release_active_accept_held_impl(&mut self) -> bool {
        if !(self.phone_ops_enabled || self.mps_qualification_enabled)
            || self.phone_state.state != CallState::Idle
        {
        if !(self.phone_ops_enabled || self.mps_qualification_enabled) {
            return false;
        }
        self.call_list.retain(|x| x.state != CallState::Active);
        self.phone_state.num_active = 0;
        // Activate the first held call
        if self.mps_qualification_enabled {
            if self.phone_state.state != CallState::Idle {
                return false;
            }
            for c in self.call_list.iter_mut() {
                if c.state == CallState::Held {
                    c.state = CallState::Active;
@@ -2030,16 +2044,28 @@ impl BluetoothMedia {
                    break;
                }
            }
        } else if self.phone_ops_enabled {
            for c in self.call_list.iter_mut() {
                if c.state == CallState::Incoming && self.phone_state.state == CallState::Incoming {
                    c.state = CallState::Active;
                    self.phone_state.num_active += 1;
                    self.phone_state.state = CallState::Idle;
                    break;
                }
            }
        }
        true
    }

    fn hold_active_accept_held_impl(&mut self) -> bool {
        if !(self.phone_ops_enabled || self.mps_qualification_enabled)
            || self.phone_state.state != CallState::Idle
        {
        if !(self.phone_ops_enabled || self.mps_qualification_enabled) {
            return false;
        }

        if self.mps_qualification_enabled {
            if self.phone_state.state != CallState::Idle {
                return false;
            }
            self.phone_state.num_held += self.phone_state.num_active;
            self.phone_state.num_active = 0;

@@ -2057,6 +2083,9 @@ impl BluetoothMedia {
                    _ => {}
                }
            }
        } else if self.phone_ops_enabled {
            return false;
        }
        true
    }