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

Commit 89f8dc61 authored by howardchung's avatar howardchung
Browse files

Floss: Allow disabling one of HIDP or HOGP in EP

With the support of libbluetooth, we are able to disable one of the HIDP
or HOGP in hid host.

Bug: 263755727
Test: The below operations are tested from D-Bus layer
1. set service allowlist to empty, check both classic and LE HID are
   functioning.
2. set service allowlist to HIDP only, check only classic HID is
   functioning.
3. set service allowlist to HOGP only, check only LE HID is functioning.
4. set service allowlist to 00000000-0000-0000-0000-000000000000, check
   both classic and LE HID are not functioning.
Tag: #floss

Change-Id: I88b88bd8f84cc7bc218509e80da726758fb80677
parent b242301a
Loading
Loading
Loading
Loading
+30 −3
Original line number Diff line number Diff line
@@ -489,7 +489,11 @@ impl Bluetooth {

        match profile {
            Profile::Hid => {
                self.hh.as_mut().unwrap().disable();
                self.hh.as_mut().unwrap().activate_hidp(false);
            }

            Profile::Hogp => {
                self.hh.as_mut().unwrap().activate_hogp(false);
            }

            Profile::A2dpSource | Profile::Hfp => {
@@ -507,7 +511,11 @@ impl Bluetooth {

        match profile {
            Profile::Hid => {
                self.hh.as_mut().unwrap().enable();
                self.hh.as_mut().unwrap().activate_hidp(true);
            }

            Profile::Hogp => {
                self.hh.as_mut().unwrap().activate_hogp(true);
            }

            Profile::A2dpSource | Profile::Hfp => {
@@ -524,7 +532,9 @@ impl Bluetooth {
        }

        match profile {
            Profile::Hid => Some(!self.hh.is_none() && self.hh.as_ref().unwrap().is_enabled()),
            Profile::Hid => Some(self.hh.as_ref().unwrap().is_hidp_activated),

            Profile::Hogp => Some(self.hh.as_ref().unwrap().is_hogp_activated),

            Profile::A2dpSource | Profile::Hfp => {
                self.bluetooth_media.lock().unwrap().is_profile_enabled(profile)
@@ -550,6 +560,23 @@ impl Bluetooth {
                }
            }
        }

        if self.hh.as_mut().unwrap().configure_enabled_profiles() {
            self.hh.as_mut().unwrap().disable();
            let txl = self.tx.clone();

            tokio::spawn(async move {
                // Wait 100 milliseconds to prevent race condition caused by quick disable then
                // enable.
                // TODO: (b/272191117): don't enable until we're sure disable is done.
                tokio::time::sleep(Duration::from_millis(100)).await;
                let _ = txl.send(Message::HidHostEnable).await;
            });
        }
    }

    pub fn enable_hidhost(&mut self) {
        self.hh.as_mut().unwrap().enable();
    }

    pub fn init_profiles(&mut self) {
+4 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ pub enum Message {

    // Admin policy related
    AdminCallbackDisconnected(u32),
    HidHostEnable,
}

/// Represents suspend mode of a module.
@@ -317,6 +318,9 @@ impl Stack {
                Message::AdminCallbackDisconnected(id) => {
                    bluetooth_admin.lock().unwrap().unregister_admin_policy_callback(id);
                }
                Message::HidHostEnable => {
                    bluetooth.lock().unwrap().enable_hidhost();
                }
            }
        }
    }
+35 −0
Original line number Diff line number Diff line
@@ -160,6 +160,9 @@ pub struct HidHost {
    internal: RawHHWrapper,
    is_init: bool,
    _is_enabled: bool,
    pub is_hogp_activated: bool,
    pub is_hidp_activated: bool,
    pub is_profile_updated: bool,
    // Keep callback object in memory (underlying code doesn't make copy)
    callbacks: Option<Box<bindings::bthh_callbacks_t>>,
}
@@ -193,6 +196,9 @@ impl HidHost {
            internal: RawHHWrapper { raw: r as *const bthh_interface_t },
            is_init: false,
            _is_enabled: false,
            is_hogp_activated: false,
            is_hidp_activated: false,
            is_profile_updated: false,
            callbacks: None,
        }
    }
@@ -349,6 +355,35 @@ impl HidHost {
        ))
    }

    /// return true if we need to restart hh
    #[profile_enabled_or(true)]
    pub fn configure_enabled_profiles(&mut self) -> bool {
        let needs_restart = self.is_profile_updated;
        if self.is_profile_updated {
            ccall!(
                self,
                configure_enabled_profiles,
                self.is_hidp_activated,
                self.is_hogp_activated
            );
            self.is_profile_updated = false;
        }
        needs_restart
    }

    pub fn activate_hogp(&mut self, active: bool) {
        if self.is_hogp_activated != active {
            self.is_hogp_activated = active;
            self.is_profile_updated = true;
        }
    }

    pub fn activate_hidp(&mut self, active: bool) {
        if self.is_hidp_activated != active {
            self.is_hidp_activated = active;
            self.is_profile_updated = true;
        }
    }
    #[profile_enabled_or]
    pub fn cleanup(&mut self) {
        ccall!(self, cleanup)