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

Commit ea17fc41 authored by WhaleChang's avatar WhaleChang
Browse files

Floss: Prevent phone state desync with AG when answering/hanging up by HF.

For whatever reason(like network unstable), the call event sometimes not be able
correctly propagated to Call Center App.
When that happens, headset call state will desync with App because we
change the call state in HFP callback.

Fix the problem by only sending UHID event to App in HFP callback, and wait
until App sync the call state in dispatch UHID output.

Because when doing MPS qualification, there is no real app engage.
so here we directly jump right in to the telephony ops implementation

Bug: 331875859
Test: Conduct the following manual tests
  pair Bluetooth Headset
  Google Meet: headset is able hang-up the call
Test: Conduct the following manual tests
  pair Bluetooth Headset
  login Ring Central and place an incoming-call
  answer the call by headset
  hangup the call by headset
Test: Conduct the following manual tests
  pair Bluetooth Headset
  login Ring Central and place an incoming-call
  answer the call on Ring Central
  hangup the call from headset
Test: atest bluetooth_test_gd
Tag: #floss
Flag: EXEMPT, no behavior change on Android; Floss-only changes
Change-Id: I8e75725dbb3c8108fd81f6da3a311289d4177719
parent 8813e967
Loading
Loading
Loading
Loading
+28 −6
Original line number Diff line number Diff line
@@ -848,12 +848,14 @@ impl BluetoothMedia {

                if let Some(uhid) = self.uhid.get_mut(&addr) {
                    if volume == 0 && !uhid.muted {
                        uhid.muted = true;
                        // We expect the application to send back UHID output report and
                        // update uhid.mute in dispatch_uhid_hfp_output_callback later.
                        self.uhid_send_phone_mute_input_report(&addr, true);
                    } else if volume > 0 {
                        uhid.volume = volume;
                        if uhid.muted {
                            uhid.muted = false;
                            // We expect the application to send back UHID output report and
                            // update uhid.mute in dispatch_uhid_hfp_output_callback later.
                            self.uhid_send_phone_mute_input_report(&addr, false);
                        }
                    }
@@ -1004,9 +1006,19 @@ impl BluetoothMedia {
                    warn!("Unexpected answer call. phone_ops_enabled and mps_qualification_enabled does not enabled.");
                    return;
                }
                self.answer_call_impl();
                if self.mps_qualification_enabled {
                    // In qualification mode we expect no application to interact with.
                    // So we just jump right in to the telephony ops implementation.
                    let id = BLUETOOTH_TELEPHONY_UHID_REPORT_ID;
                    let mut data = UHID_OUTPUT_NONE;
                    data |= UHID_OUTPUT_OFF_HOOK;
                    self.dispatch_uhid_hfp_output_callback(addr.to_string(), id, data);
                } else {
                    // We expect the application to send back UHID output report and
                    // trigger dispatch_uhid_hfp_output_callback later.
                    self.uhid_send_hook_switch_input_report(&addr, true);
                }
            }
            HfpCallbacks::HangupCall(addr) => {
                if !self.phone_ops_enabled && !self.mps_qualification_enabled {
                    warn!("Unexpected hangup call. phone_ops_enabled and mps_qualification_enabled does not enabled.");
@@ -1021,9 +1033,19 @@ impl BluetoothMedia {
                    );
                    return;
                }
                self.hangup_call_impl();
                if self.mps_qualification_enabled {
                    // In qualification mode we expect no application to interact with.
                    // So we just jump right in to the telephony ops implementation.
                    let id = BLUETOOTH_TELEPHONY_UHID_REPORT_ID;
                    let mut data = UHID_OUTPUT_NONE;
                    data &= !UHID_OUTPUT_OFF_HOOK;
                    self.dispatch_uhid_hfp_output_callback(addr.to_string(), id, data);
                } else {
                    // We expect the application to send back UHID output report and
                    // trigger dispatch_uhid_hfp_output_callback later.
                    self.uhid_send_hook_switch_input_report(&addr, false);
                }
            }
            HfpCallbacks::DialCall(number, addr) => {
                if !self.mps_qualification_enabled {
                    warn!("Unexpected dail call. mps_qualification_enabled does not enabled.");