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

Commit 9590264c authored by Jeremy Wu's avatar Jeremy Wu Committed by Gerrit Code Review
Browse files

Merge "floss: reject media profile connections for second device" into main

parents ee8e422f 04d57ac3
Loading
Loading
Loading
Loading
+71 −20
Original line number Diff line number Diff line
@@ -472,7 +472,6 @@ pub struct BluetoothMedia {
    adapter: Arc<Mutex<Box<Bluetooth>>>,
    a2dp: A2dp,
    avrcp: Avrcp,
    avrcp_address: Option<RawAddress>,
    avrcp_states: HashMap<RawAddress, BtavConnectionState>,
    a2dp_states: HashMap<RawAddress, BtavConnectionState>,
    a2dp_audio_state: HashMap<RawAddress, BtavAudioState>,
@@ -549,7 +548,6 @@ impl BluetoothMedia {
            adapter,
            a2dp,
            avrcp,
            avrcp_address: None,
            avrcp_states: HashMap::new(),
            a2dp_states: HashMap::new(),
            a2dp_audio_state: HashMap::new(),
@@ -637,7 +635,13 @@ impl BluetoothMedia {
            return;
        }

        self.connected_profiles.entry(addr).or_default().remove(&profile);
        if let Some(profiles) = self.connected_profiles.get_mut(&addr) {
            profiles.remove(&profile);
            if profiles.is_empty() {
                self.connected_profiles.remove(&addr);
            }
        }

        self.delay_volume_update.remove(&profile);

        if is_profile_critical && self.is_complete_profiles_required() {
@@ -1247,12 +1251,31 @@ impl BluetoothMedia {
                    BtavConnectionState::Connected => {
                        info!("[{}]: a2dp connected.", DisplayAddress(&addr));

                        if !self.connected_profiles.is_empty()
                            && !self.connected_profiles.contains_key(&addr)
                        {
                            warn!(
                                "Another media connection exists. Disconnect a2dp from {}",
                                DisplayAddress(&addr)
                            );
                            self.a2dp.disconnect(addr);
                            return;
                        }

                        self.a2dp_states.insert(addr, state);
                        self.add_connected_profile(addr, Profile::A2dpSink);
                    }
                    BtavConnectionState::Disconnected => {
                        info!("[{}]: a2dp disconnected.", DisplayAddress(&addr));

                        if !self.connected_profiles.contains_key(&addr) {
                            warn!(
                                "Ignoring non-primary a2dp disconnection from {}",
                                DisplayAddress(&addr)
                            );
                            return;
                        }

                        if self.a2dp_audio_connection_listener.is_some() {
                            let listener = self.a2dp_audio_connection_listener.take().unwrap();
                            let data: Vec<u8> = vec![0];
@@ -1325,14 +1348,19 @@ impl BluetoothMedia {
                    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));
                if !self.connected_profiles.is_empty()
                    && !self.connected_profiles.contains_key(&addr)
                {
                    warn!(
                        "Another media connection exists. Disconnect avrcp from {}",
                        DisplayAddress(&addr)
                    );
                    self.avrcp.disconnect(addr);
                    return;
                }
                self.avrcp_address = Some(addr);

                self.avrcp_states.insert(addr, BtavConnectionState::Connected);

                match self.uinput.create(self.adapter_get_remote_name(addr), addr.to_string()) {
                    Ok(()) => info!("uinput device created for: {}", DisplayAddress(&addr)),
@@ -1373,13 +1401,15 @@ impl BluetoothMedia {
                    BtStatus::Success,
                    BtavConnectionState::Disconnected as u32,
                );
                self.avrcp_states.remove(&addr);

                if self.avrcp_address != Some(addr) {
                    // Ignore disconnection to address we don't care
                if !self.connected_profiles.contains_key(&addr) {
                    warn!(
                        "Ignoring non-primary avrcp disconnection from {}",
                        DisplayAddress(&addr)
                    );
                    return;
                }
                self.avrcp_address = None;
                self.avrcp_states.remove(&addr);

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

@@ -1481,6 +1511,18 @@ impl BluetoothMedia {
                    }
                    BthfConnectionState::SlcConnected => {
                        info!("[{}]: hfp slc connected.", DisplayAddress(&addr));

                        if !self.connected_profiles.is_empty()
                            && !self.connected_profiles.contains_key(&addr)
                        {
                            warn!(
                                "Another media connection exists. Disconnect hfp from {}",
                                DisplayAddress(&addr)
                            );
                            self.hfp.disconnect(addr);
                            return;
                        }

                        // The device may not support codec-negotiation,
                        // in which case we shall assume it supports CVSD at this point.
                        self.hfp_cap.entry(addr).or_insert(HfpCodecFormat::CVSD);
@@ -1500,6 +1542,14 @@ impl BluetoothMedia {
                    BthfConnectionState::Disconnected => {
                        info!("[{}]: hfp disconnected.", DisplayAddress(&addr));

                        if !self.connected_profiles.contains_key(&addr) {
                            warn!(
                                "Ignoring non-primary hfp disconnection from {}",
                                DisplayAddress(&addr)
                            );
                            return;
                        }

                        if self.hfp_audio_connection_listener.is_some() {
                            let listener = self.hfp_audio_connection_listener.take().unwrap();
                            let data: Vec<u8> = vec![0];
@@ -2271,7 +2321,7 @@ impl BluetoothMedia {
        let mut states = self.device_states.lock().unwrap();
        let mut first_conn_ts = Instant::now();

        let is_profile_cleared = self.connected_profiles.get(&addr).unwrap().is_empty();
        let is_profile_cleared = !self.connected_profiles.contains_key(&addr);

        if let Some(task) = guard.get(&addr) {
            if let Some((handler, ts)) = task {
@@ -2315,7 +2365,6 @@ impl BluetoothMedia {
        // Cleanup if transitioning to empty set.
        if is_profile_cleared {
            info!("[{}]: Device connection state: Disconnected.", DisplayAddress(&addr));
            self.connected_profiles.remove(&addr);
            states.remove(&addr);
            guard.remove(&addr);
            let tx = self.tx.clone();
@@ -3282,11 +3331,11 @@ impl IBluetoothMedia for BluetoothMedia {
            available_profiles
        );

        let connected_profiles = self.connected_profiles.entry(addr).or_default();
        let connected_profiles = self.connected_profiles.get(&addr).cloned().unwrap_or_default();

        // Sort here so the order of connection is always consistent
        let missing_profiles =
            available_profiles.difference(connected_profiles).sorted().collect::<Vec<_>>();
            available_profiles.difference(&connected_profiles).sorted().collect::<Vec<_>>();

        // Connect the profiles one-by-one so it won't stuck at the lower layer.
        // Therefore, just connect to one profile for now.
@@ -3581,10 +3630,6 @@ 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,
@@ -3594,7 +3639,13 @@ impl IBluetoothMedia for BluetoothMedia {
            }
        };

        self.avrcp.set_volume(self.avrcp_address.unwrap(), vol);
        // There is always no more than one active media connection, which
        // implies only one address is connected with AVRCP.
        for (addr, profiles) in &self.connected_profiles {
            if profiles.contains(&Profile::AvrcpController) {
                self.avrcp.set_volume(*addr, vol);
            }
        }
    }

    fn set_hfp_volume(&mut self, volume: u8, addr: RawAddress) {