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

Commit 6cf31b86 authored by Abhishek Pandit-Subedi's avatar Abhishek Pandit-Subedi Committed by Abhishek Pandit-Subedi
Browse files

floss: Refactor DisconnectWatcher to take id

Refactor disconnect watcher to associate an id with a callback for
disconnection. This will allow us to verify that a disconnect request
for an id is allowed for a specific client.

Bug: 201599762
Tag: #floss
Test: Verify btclient continues working on ChromeOS
Change-Id: Ia019ad2d9af82be6e1e4eb2d7399bdaadb1600ab
parent 845b4e90
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -37,11 +37,15 @@ impl IBluetoothManagerCallback for BtManagerCallback {
}

impl manager_service::RPCProxy for BtManagerCallback {
    fn register_disconnect(&mut self, _f: Box<dyn Fn() + Send>) {}
    fn register_disconnect(&mut self, _id: u32, _f: Box<dyn Fn(u32) + Send>) {}

    fn get_object_id(&self) -> String {
        self.objpath.clone()
    }

    fn unregister(&mut self, _id: u32) -> bool {
        false
    }
}

/// Callback container for adapter interface callbacks.
@@ -109,11 +113,15 @@ impl IBluetoothCallback for BtCallback {
}

impl RPCProxy for BtCallback {
    fn register_disconnect(&mut self, _f: Box<dyn Fn() + Send>) {}
    fn register_disconnect(&mut self, _id: u32, _f: Box<dyn Fn(u32) + Send>) {}

    fn get_object_id(&self) -> String {
        self.objpath.clone()
    }

    fn unregister(&mut self, _id: u32) -> bool {
        false
    }
}

pub(crate) struct BtGattCallback {
@@ -256,9 +264,13 @@ impl IBluetoothGattCallback for BtGattCallback {
}

impl RPCProxy for BtGattCallback {
    fn register_disconnect(&mut self, _f: Box<dyn Fn() + Send>) {}
    fn register_disconnect(&mut self, _id: u32, _f: Box<dyn Fn(u32) + Send>) {}

    fn get_object_id(&self) -> String {
        self.objpath.clone()
    }

    fn unregister(&mut self, _id: u32) -> bool {
        false
    }
}
+12 −3
Original line number Diff line number Diff line
@@ -140,10 +140,13 @@ struct IBluetoothCallbackDBus {}

impl btstack::RPCProxy for IBluetoothCallbackDBus {
    // Dummy implementations just to satisfy impl RPCProxy requirements.
    fn register_disconnect(&mut self, _f: Box<dyn Fn() + Send>) {}
    fn register_disconnect(&mut self, _id: u32, _f: Box<dyn Fn(u32) + Send>) {}
    fn get_object_id(&self) -> String {
        String::from("")
    }
    fn unregister(&mut self, _id: u32) -> bool {
        false
    }
}

#[generate_dbus_exporter(
@@ -375,10 +378,13 @@ struct IBluetoothManagerCallbackDBus {}

impl manager_service::RPCProxy for IBluetoothManagerCallbackDBus {
    // Placeholder implementations just to satisfy impl RPCProxy requirements.
    fn register_disconnect(&mut self, _f: Box<dyn Fn() + Send>) {}
    fn register_disconnect(&mut self, _id: u32, _f: Box<dyn Fn(u32) + Send>) {}
    fn get_object_id(&self) -> String {
        String::from("")
    }
    fn unregister(&mut self, _id: u32) -> bool {
        false
    }
}

#[generate_dbus_exporter(
@@ -600,10 +606,13 @@ struct IBluetoothGattCallbackDBus {}

impl btstack::RPCProxy for IBluetoothGattCallbackDBus {
    // Placeholder implementations just to satisfy impl RPCProxy requirements.
    fn register_disconnect(&mut self, _f: Box<dyn Fn() + Send>) {}
    fn register_disconnect(&mut self, _id: u32, _f: Box<dyn Fn(u32) + Send>) {}
    fn get_object_id(&self) -> String {
        String::from("")
    }
    fn unregister(&mut self, _id: u32) -> bool {
        false
    }
}

#[generate_dbus_exporter(
+8 −3
Original line number Diff line number Diff line
@@ -431,10 +431,11 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream {
        #ori_item

        impl RPCProxy for #self_ty {
            fn register_disconnect(&mut self, _disconnect_callback: Box<dyn Fn() + Send>) {}
            fn register_disconnect(&mut self, _id: u32, _disconnect_callback: Box<dyn Fn(u32) + Send>) {}
            fn get_object_id(&self) -> String {
                String::from("")
            }
            fn unregister(&mut self, _id: u32) -> bool { false }
        }

        struct #struct_ident {
@@ -449,13 +450,17 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream {
        }

        impl RPCProxy for #struct_ident {
            fn register_disconnect(&mut self, disconnect_callback: Box<dyn Fn() + Send>) {
                self.disconnect_watcher.lock().unwrap().add(self.remote.clone(), disconnect_callback);
            fn register_disconnect(&mut self, id: u32, disconnect_callback: Box<dyn Fn(u32) + Send>) {
                self.disconnect_watcher.lock().unwrap().add(self.remote.clone(), id, disconnect_callback);
            }

            fn get_object_id(&self) -> String {
                self.objpath.to_string().clone()
            }

            fn unregister(&mut self, id: u32) -> bool {
                self.disconnect_watcher.lock().unwrap().remove(self.remote.clone(), id)
            }
        }

        impl DBusArg for Box<dyn #trait_ + Send> {
+23 −5
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ use std::sync::{Arc, Mutex};

/// A D-Bus "NameOwnerChanged" handler that continuously monitors client disconnects.
pub struct DisconnectWatcher {
    callbacks: Arc<Mutex<HashMap<BusName<'static>, Vec<Box<dyn Fn() + Send>>>>>,
    callbacks: Arc<Mutex<HashMap<BusName<'static>, Vec<(u32, Box<dyn Fn(u32) + Send>)>>>>,
}

impl DisconnectWatcher {
@@ -67,12 +67,12 @@ impl DisconnectWatcher {

impl DisconnectWatcher {
    /// Adds a client address to be monitored for disconnect events.
    pub fn add(&mut self, address: BusName<'static>, callback: Box<dyn Fn() + Send>) {
    pub fn add(&mut self, address: BusName<'static>, id: u32, callback: Box<dyn Fn(u32) + Send>) {
        if !self.callbacks.lock().unwrap().contains_key(&address) {
            self.callbacks.lock().unwrap().insert(address.clone(), vec![]);
        }

        (*self.callbacks.lock().unwrap().get_mut(&address).unwrap()).push(callback);
        (*self.callbacks.lock().unwrap().get_mut(&address).unwrap()).push((id, callback));
    }

    /// Sets up the D-Bus handler that monitors client disconnects.
@@ -104,8 +104,8 @@ impl DisconnectWatcher {
                    return true;
                }

                for callback in &callbacks_map.lock().unwrap()[&addr] {
                    callback();
                for (id, callback) in &callbacks_map.lock().unwrap()[&addr] {
                    callback(*id);
                }

                callbacks_map.lock().unwrap().remove(&addr);
@@ -114,6 +114,24 @@ impl DisconnectWatcher {
            }),
        );
    }

    /// Removes callback by id if owned by the specific busname.
    pub fn remove(&mut self, address: BusName<'static>, target_id: u32) -> bool {
        if !self.callbacks.lock().unwrap().contains_key(&address) {
            return false;
        }

        match self.callbacks.lock().unwrap()[&address].iter().position(|x| x.0 == target_id) {
            Some(index) => {
                let (id, callback) = &self.callbacks.lock().unwrap()[&address][index];
                callback(*id);
                let _ =
                    self.callbacks.lock().unwrap().get_mut(&address).unwrap().swap_remove(index);
                true
            }
            None => false,
        }
    }
}

/// Implements `DBusArg` for an enum.
+17 −9
Original line number Diff line number Diff line
@@ -60,6 +60,11 @@ impl BluetoothManager {
        }
    }

    fn get_next_id(&mut self) -> u32 {
        self.callbacks_last_id += 1;
        self.callbacks_last_id
    }

    pub(crate) fn callback_disconnected(&mut self, id: u32) {
        self.callbacks.retain(|x| x.0 != id);
    }
@@ -106,15 +111,18 @@ impl IBluetoothManager for BluetoothManager {
    fn register_callback(&mut self, mut callback: Box<dyn IBluetoothManagerCallback + Send>) {
        let tx = self.manager_context.proxy.get_tx();

        self.callbacks_last_id += 1;
        let id = self.callbacks_last_id;
        let id = self.get_next_id();

        callback.register_disconnect(Box::new(move || {
        callback.register_disconnect(
            id,
            Box::new(move |cb_id| {
                let tx = tx.clone();
                tokio::spawn(async move {
                let _result = tx.send(state_machine::Message::CallbackDisconnected(id)).await;
                    let _result =
                        tx.send(state_machine::Message::CallbackDisconnected(cb_id)).await;
                });
        }));
            }),
        );

        self.callbacks.push((id, callback));
    }
Loading