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

Commit 4dd4bf1f authored by Michael Sun's avatar Michael Sun
Browse files

floss: metrics: start processing HFP and AVRCP profile metrics

Add HFP and AVRCP cases in the metric event processing to map their
connection state to the standard ENUM.

Added an AVRCP direction parameter as AVRCP profile to get
(dis)connecting state from the btif. Hence a device-initiated action
will be missing the ING state.

BUG: 240781725
Tag: #floss
Test: ./build.py
Test: emerge-${BOARD} floss
Test: gd/cert/run
Change-Id: Ia2fbb476e7b2352f75b1876f215c36914a52d7fe
parent 61451cc6
Loading
Loading
Loading
Loading
+44 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "hci/hci_packets.h"
#include "include/hardware/bluetooth.h"
#include "include/hardware/bt_av.h"
#include "include/hardware/bt_hf.h"
#include "include/hardware/bt_hh.h"

namespace bluetooth {
@@ -34,6 +35,8 @@ typedef bt_status_t BtStatus;
typedef btav_connection_state_t BtavConnectionState;
// topshim::profile::hid_host::BthhConnectionState is a copy of hardware/bt_hh.h:bthh_connection_state_t
typedef bthh_connection_state_t BthhConnectionState;
// topshim::profile::hid_host::BthfConnectionState is a copy of hardware/bt_hh.h:bthf_connection_state_t
typedef headset::bthf_connection_state_t BthfConnectionState;

// A copy of topshim::btif::BtDeviceType
enum class BtDeviceType {
@@ -355,9 +358,48 @@ static std::pair<uint32_t, uint32_t> ToProfileConnectionState(uint32_t profile,
    // case ProfilesFloss::AdvAudioDist:
    // case ProfilesFloss::Hsp:
    // case ProfilesFloss::HspAg:
    // case ProfilesFloss::Hfp:
    case ProfilesFloss::Hfp:
      output.first = (uint32_t)Profile::HFP;
      switch ((BthfConnectionState)state) {
        case BthfConnectionState::BTHF_CONNECTION_STATE_DISCONNECTED:
          output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
          break;
        case BthfConnectionState::BTHF_CONNECTION_STATE_CONNECTING:
          output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
          break;
        case BthfConnectionState::BTHF_CONNECTION_STATE_CONNECTED:
        case BthfConnectionState::BTHF_CONNECTION_STATE_SLC_CONNECTED:
          output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
          break;
        case BthfConnectionState::BTHF_CONNECTION_STATE_DISCONNECTING:
          output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
          break;
        default:
          output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
          break;
      }
      break;
    // case ProfilesFloss::HfpAg:
    // case ProfilesFloss::AvrcpController:
    case ProfilesFloss::AvrcpController:
      output.first = (uint32_t)Profile::AVRCP;
      switch ((BtavConnectionState)state) {
        case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTED:
          output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
          break;
        case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTING:
          output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
          break;
        case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTED:
          output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
          break;
        case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTING:
          output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
          break;
        default:
          output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
          break;
      }
      break;
    // case ProfilesFloss::AvrcpTarget:
    // case ProfilesFloss::ObexObjectPush:
    case ProfilesFloss::Hid:
+33 −1
Original line number Diff line number Diff line
//! Anything related to audio and media API.

use bt_topshim::btif::{BluetoothInterface, BtStatus, RawAddress};
use bt_topshim::btif::{BluetoothInterface, BtConnectionDirection, BtStatus, RawAddress};
use bt_topshim::profiles::a2dp::{
    A2dp, A2dpCallbacks, A2dpCallbacksDispatcher, A2dpCodecBitsPerSample, A2dpCodecChannelMode,
    A2dpCodecConfig, A2dpCodecSampleRate, BtavAudioState, BtavConnectionState,
@@ -151,6 +151,7 @@ pub struct BluetoothMedia {
    adapter: Option<Arc<Mutex<Box<Bluetooth>>>>,
    a2dp: Option<A2dp>,
    avrcp: Option<Avrcp>,
    avrcp_direction: BtConnectionDirection,
    a2dp_states: HashMap<RawAddress, BtavConnectionState>,
    a2dp_audio_state: HashMap<RawAddress, BtavAudioState>,
    hfp: Option<Hfp>,
@@ -178,6 +179,7 @@ impl BluetoothMedia {
            adapter: None,
            a2dp: None,
            avrcp: None,
            avrcp_direction: BtConnectionDirection::Unknown,
            a2dp_states: HashMap::new(),
            a2dp_audio_state: HashMap::new(),
            hfp: None,
@@ -301,12 +303,24 @@ impl BluetoothMedia {

                self.absolute_volume = supported;

                // If is device initiated the AVRCP connection, emit a fake connecting state as
                // stack don't receive one.
                if self.avrcp_direction != BtConnectionDirection::Outgoing {
                    metrics::profile_connection_state_changed(
                        addr,
                        Profile::AvrcpController as u32,
                        BtStatus::Success,
                        BtavConnectionState::Connecting as u32,
                    );
                }
                metrics::profile_connection_state_changed(
                    addr,
                    Profile::AvrcpController as u32,
                    BtStatus::Success,
                    BtavConnectionState::Connected as u32,
                );
                // Reset direction to unknown.
                self.avrcp_direction = BtConnectionDirection::Unknown;

                self.add_connected_profile(addr, uuid::Profile::AvrcpController);
            }
@@ -325,12 +339,24 @@ impl BluetoothMedia {
                    None => false,
                };

                // If the peer device initiated the AVRCP disconnection, emit a fake connecting
                // state as stack don't receive one.
                if self.avrcp_direction != BtConnectionDirection::Outgoing {
                    metrics::profile_connection_state_changed(
                        addr,
                        Profile::AvrcpController as u32,
                        BtStatus::Success,
                        BtavConnectionState::Disconnecting as u32,
                    );
                }
                metrics::profile_connection_state_changed(
                    addr,
                    Profile::AvrcpController as u32,
                    BtStatus::Success,
                    BtavConnectionState::Disconnected as u32,
                );
                // Reset direction to unknown.
                self.avrcp_direction = BtConnectionDirection::Unknown;

                self.rm_connected_profile(
                    addr,
@@ -816,8 +842,11 @@ impl IBluetoothMedia for BluetoothMedia {
                    );
                    match self.avrcp.as_mut() {
                        Some(avrcp) => {
                            self.avrcp_direction = BtConnectionDirection::Outgoing;
                            let status: BtStatus = avrcp.connect(addr);
                            if BtStatus::Success != status {
                                // Reset direction to unknown.
                                self.avrcp_direction = BtConnectionDirection::Unknown;
                                metrics::profile_connection_state_changed(
                                    addr,
                                    Profile::AvrcpController as u32,
@@ -938,8 +967,11 @@ impl IBluetoothMedia for BluetoothMedia {
                    );
                    match self.avrcp.as_mut() {
                        Some(avrcp) => {
                            self.avrcp_direction = BtConnectionDirection::Outgoing;
                            let status: BtStatus = avrcp.disconnect(addr);
                            if BtStatus::Success != status {
                                // Reset direction to unknown.
                                self.avrcp_direction = BtConnectionDirection::Unknown;
                                metrics::profile_connection_state_changed(
                                    addr,
                                    Profile::AvrcpController as u32,
+14 −0
Original line number Diff line number Diff line
@@ -202,6 +202,20 @@ pub enum BtStatus {
    Unknown = 0xff,
}

#[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
#[repr(u32)]
pub enum BtConnectionDirection {
    Unknown = 0,
    Outgoing,
    Incoming,
}

impl From<u32> for BtConnectionDirection {
    fn from(item: u32) -> Self {
        BtConnectionDirection::from_u32(item).unwrap_or(BtConnectionDirection::Unknown)
    }
}

pub fn ascii_to_string(data: &[u8], length: usize) -> String {
    // We need to reslice data because from_utf8 tries to interpret the
    // whole slice and not just what is before the null terminated portion
+1 −1
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ pub struct A2dpError {
    /// Standard BT status come from a function return or the cloest approximation to the real
    /// error.
    pub status: BtStatus,
    /// An additional value to help explain the error. In the A2Dp context, this is often referring
    /// An additional value to help explain the error. In the A2DP context, this is often referring
    /// to the BTA_AV_XXX status.
    pub error: i32,
    /// An optional error message that the lower layer wants to deliver.