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

Commit c46353df authored by Archie Pusaka's avatar Archie Pusaka Committed by Gerrit Code Review
Browse files

Merge "Floss: Support multiple volume callbacks" into main

parents 47a96400 29b039b9
Loading
Loading
Loading
Loading
+55 −39
Original line number Diff line number Diff line
//! Anything related to audio and media API.

use bt_topshim::btif::{
    BluetoothInterface, BtBondState, BtConnectionDirection, BtStatus, BtTransport, DisplayAddress,
    RawAddress, ToggleableProfile,
    BluetoothInterface, BtBondState, BtStatus, BtTransport, DisplayAddress, RawAddress,
    ToggleableProfile,
};
use bt_topshim::profiles::a2dp::{
    A2dp, A2dpCallbacks, A2dpCallbacksDispatcher, A2dpCodecBitsPerSample, A2dpCodecChannelMode,
@@ -472,7 +472,8 @@ pub struct BluetoothMedia {
    adapter: Arc<Mutex<Box<Bluetooth>>>,
    a2dp: A2dp,
    avrcp: Avrcp,
    avrcp_direction: BtConnectionDirection,
    avrcp_address: Option<RawAddress>,
    avrcp_states: HashMap<RawAddress, BtavConnectionState>,
    a2dp_states: HashMap<RawAddress, BtavConnectionState>,
    a2dp_audio_state: HashMap<RawAddress, BtavAudioState>,
    a2dp_has_interrupted_stream: bool, // Only used for qualification.
@@ -548,7 +549,8 @@ impl BluetoothMedia {
            adapter,
            a2dp,
            avrcp,
            avrcp_direction: BtConnectionDirection::Unknown,
            avrcp_address: None,
            avrcp_states: HashMap::new(),
            a2dp_states: HashMap::new(),
            a2dp_audio_state: HashMap::new(),
            a2dp_has_interrupted_stream: false,
@@ -1307,6 +1309,31 @@ impl BluetoothMedia {
                    supported
                );

                // If is device initiated the AVRCP connection, emit a fake connecting state as
                // stack don't receive one.
                if self.avrcp_states.get(&addr) != Some(&BtavConnectionState::Connecting) {
                    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,
                );
                self.avrcp_states.insert(addr, BtavConnectionState::Connected);

                if self.avrcp_address.is_some() {
                    warn!("Another AVRCP connection exists. Disconnect {}", DisplayAddress(&addr));
                    self.avrcp.disconnect(addr);
                    return;
                }
                self.avrcp_address = Some(addr);

                match self.uinput.create(self.adapter_get_remote_name(addr), addr.to_string()) {
                    Ok(()) => info!("uinput device created for: {}", DisplayAddress(&addr)),
                    Err(e) => warn!("{}", e),
@@ -1325,30 +1352,34 @@ impl BluetoothMedia {
                }

                self.absolute_volume = supported;
                self.add_connected_profile(addr, Profile::AvrcpController);
            }
            AvrcpCallbacks::AvrcpDeviceDisconnected(addr) => {
                info!("[{}]: avrcp disconnected.", DisplayAddress(&addr));

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

                self.add_connected_profile(addr, Profile::AvrcpController);
                if self.avrcp_address != Some(addr) {
                    // Ignore disconnection to address we don't care
                    return;
                }
            AvrcpCallbacks::AvrcpDeviceDisconnected(addr) => {
                info!("[{}]: avrcp disconnected.", DisplayAddress(&addr));
                self.avrcp_address = None;

                self.uinput.close(addr.to_string());

@@ -1362,25 +1393,6 @@ 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, Profile::AvrcpController, is_profile_critical);
            }
            AvrcpCallbacks::AvrcpAbsoluteVolumeUpdate(volume) => {
@@ -3336,11 +3348,11 @@ impl IBluetoothMedia for BluetoothMedia {
                        BtStatus::Success,
                        BtavConnectionState::Connecting as u32,
                    );
                    self.avrcp_direction = BtConnectionDirection::Outgoing;
                    self.avrcp_states.insert(addr, BtavConnectionState::Connecting);
                    let status = self.avrcp.connect(addr);
                    if BtStatus::Success != status {
                        // Reset direction to unknown.
                        self.avrcp_direction = BtConnectionDirection::Unknown;
                        self.avrcp_states.remove(&addr);
                        metrics::profile_connection_state_changed(
                            addr,
                            Profile::AvrcpController as u32,
@@ -3463,11 +3475,11 @@ impl IBluetoothMedia for BluetoothMedia {
                        BtStatus::Success,
                        BtavConnectionState::Disconnecting as u32,
                    );
                    self.avrcp_direction = BtConnectionDirection::Outgoing;
                    self.avrcp_states.insert(addr, BtavConnectionState::Disconnecting);
                    let status = self.avrcp.disconnect(addr);
                    if BtStatus::Success != status {
                        // Reset direction to unknown.
                        self.avrcp_direction = BtConnectionDirection::Unknown;
                        self.avrcp_states.remove(&addr);
                        metrics::profile_connection_state_changed(
                            addr,
                            Profile::AvrcpController as u32,
@@ -3569,6 +3581,10 @@ impl IBluetoothMedia for BluetoothMedia {
    }

    fn set_volume(&mut self, volume: u8) {
        if self.avrcp_address.is_none() {
            return;
        }

        // Guard the range 0-127 by the try_from cast from u8 to i8.
        let vol = match i8::try_from(volume) {
            Ok(val) => val,
@@ -3578,7 +3594,7 @@ impl IBluetoothMedia for BluetoothMedia {
            }
        };

        self.avrcp.set_volume(vol);
        self.avrcp.set_volume(self.avrcp_address.unwrap(), vol);
    }

    fn set_hfp_volume(&mut self, volume: u8, addr: RawAddress) {
+13 −7
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "rust/topshim/btav/btav_shim.h"

#include <cstdio>
#include <map>
#include <memory>

#include "base/functional/callback.h"
@@ -156,12 +157,12 @@ public:
  }

  void DeviceConnected(const RawAddress& addr, VolumeChangedCb cb) override {
    volumeCb = std::move(cb);
    volumeCbs[addr] = std::move(cb);
    rusty::avrcp_device_connected(addr, /*absolute_volume_enabled=*/true);
  }

  void DeviceDisconnected(const RawAddress& addr) override {
    volumeCb.Reset();
    volumeCbs.erase(addr);
    rusty::avrcp_device_disconnected(addr);
  }

@@ -175,16 +176,19 @@ public:
  }

  // Set CT's (headsets, speakers) volume.
  void SetDeviceVolume(int8_t volume) {
    if (!volumeCb || volume < 0) {
  void SetDeviceVolume(const RawAddress& addr, int8_t volume) {
    if (volume < 0) {
      return;
    }

    volumeCb.Run(volume);
    const auto& cb_iter = this->volumeCbs.find(addr);
    if (cb_iter != this->volumeCbs.end()) {
      cb_iter->second.Run(volume);
    }
  }

private:
  VolumeInterface::VolumeChangedCb volumeCb;
  std::map<RawAddress, VolumeInterface::VolumeChangedCb> volumeCbs;
};

}  // namespace bluetooth::avrcp
@@ -362,7 +366,9 @@ void AvrcpIntf::cleanup() { intf_->Cleanup(); }
uint32_t AvrcpIntf::connect(RawAddress addr) { return intf_->ConnectDevice(addr); }
uint32_t AvrcpIntf::disconnect(RawAddress addr) { return intf_->DisconnectDevice(addr); }

void AvrcpIntf::set_volume(int8_t volume) { return mVolumeInterface.SetDeviceVolume(volume); }
void AvrcpIntf::set_volume(RawAddress addr, int8_t volume) {
  return mVolumeInterface.SetDeviceVolume(addr, volume);
}

void AvrcpIntf::set_playback_status(const ::rust::String& status) {
  avrcp::PlayState state = avrcp::PlayState::STOPPED;
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public:
  uint32_t disconnect(RawAddress addr);

  // interface for Audio server
  void set_volume(int8_t volume);
  void set_volume(RawAddress addr, int8_t volume);

  void set_playback_status(const ::rust::String& status);
  void set_position(int64_t position_us);
+3 −3
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ pub mod ffi {
        fn cleanup(self: Pin<&mut AvrcpIntf>);
        fn connect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u32;
        fn disconnect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u32;
        fn set_volume(self: Pin<&mut AvrcpIntf>, volume: i8);
        fn set_volume(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress, volume: i8);
        fn set_playback_status(self: Pin<&mut AvrcpIntf>, status: &String);
        fn set_position(self: Pin<&mut AvrcpIntf>, position_us: i64);
        fn set_metadata(
@@ -173,8 +173,8 @@ impl Avrcp {
    }

    #[profile_enabled_or]
    pub fn set_volume(&mut self, volume: i8) {
        self.internal.pin_mut().set_volume(volume);
    pub fn set_volume(&mut self, addr: RawAddress, volume: i8) {
        self.internal.pin_mut().set_volume(addr, volume);
    }

    #[profile_enabled_or(false)]