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

Commit 1bb21539 authored by Hsin-chen Chuang's avatar Hsin-chen Chuang
Browse files

floss: media: Add set device status support

Add support of setting network, roaming, signal, battery status to
btclient.

The info is stored in the Floss stack and propagated to every active
HFP device when it's changed.

Bug: 214149380
Tag: #floss
Test: HFP/AG/TRS/BV-01-C, HFP/AG/PSI/*

Change-Id: Ifd95ecad9906e9dbb9feaf545a826b4cdf91c083
parent ee99347b
Loading
Loading
Loading
Loading
+85 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ use bt_topshim::profiles::hid_host::BthhReportType;
use bt_topshim::profiles::{gatt::LePhy, ProfileConnectionState};
use btstack::bluetooth::{BluetoothDevice, IBluetooth, IBluetoothQA};
use btstack::bluetooth_gatt::{GattWriteType, IBluetoothGatt, ScanSettings, ScanType};
use btstack::bluetooth_media::IBluetoothTelephony;
use btstack::socket_manager::{IBluetoothSocketManager, SocketResult};
use btstack::uuid::{Profile, UuidHelper, UuidWrapper};
use manager_service::iface_bluetooth_manager::IBluetoothManager;
@@ -271,6 +272,19 @@ fn build_commands() -> HashMap<String, CommandOption> {
            function_pointer: CommandHandler::cmd_list_devices,
        },
    );
    command_options.insert(
        String::from("telephony"),
        CommandOption {
            rules: vec![
                String::from("telephony set-network <on|off>"),
                String::from("telephony set-roaming <on|off>"),
                String::from("telephony set-signal <strength>"),
                String::from("telephony set-battery <level>"),
            ],
            description: String::from("Set device telephony status."),
            function_pointer: CommandHandler::cmd_telephony,
        },
    );
    command_options.insert(
        String::from("quit"),
        CommandOption {
@@ -1500,6 +1514,77 @@ impl CommandHandler {

        Ok(())
    }

    fn cmd_telephony(&mut self, args: &Vec<String>) -> CommandResult {
        if !self.context.lock().unwrap().adapter_ready {
            return Err(self.adapter_not_ready());
        }

        match &get_arg(args, 0)?[..] {
            "set-network" => {
                self.context
                    .lock()
                    .unwrap()
                    .telephony_dbus
                    .as_mut()
                    .unwrap()
                    .set_network_available(match &get_arg(args, 1)?[..] {
                        "on" => true,
                        "off" => false,
                        other => {
                            return Err(format!("Invalid argument '{}'", other).into());
                        }
                    });
            }
            "set-roaming" => {
                self.context.lock().unwrap().telephony_dbus.as_mut().unwrap().set_roaming(
                    match &get_arg(args, 1)?[..] {
                        "on" => true,
                        "off" => false,
                        other => {
                            return Err(format!("Invalid argument '{}'", other).into());
                        }
                    },
                );
            }
            "set-signal" => {
                let strength = String::from(get_arg(args, 1)?)
                    .parse::<i32>()
                    .or(Err("Failed parsing signal strength"))?;
                if strength < 0 || strength > 5 {
                    return Err(
                        format!("Invalid signal strength, got {}, want 0 to 5", strength).into()
                    );
                }
                self.context
                    .lock()
                    .unwrap()
                    .telephony_dbus
                    .as_mut()
                    .unwrap()
                    .set_signal_strength(strength);
            }
            "set-battery" => {
                let level = String::from(get_arg(args, 1)?)
                    .parse::<i32>()
                    .or(Err("Failed parsing battery level"))?;
                if level < 0 || level > 5 {
                    return Err(format!("Invalid battery level, got {}, want 0 to 5", level).into());
                }
                self.context
                    .lock()
                    .unwrap()
                    .telephony_dbus
                    .as_mut()
                    .unwrap()
                    .set_battery_level(level);
            }
            other => {
                return Err(format!("Invalid argument '{}'", other).into());
            }
        }
        Ok(())
    }
}

#[cfg(test)]
+38 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ use btstack::bluetooth_gatt::{
    IBluetoothGattServerCallback, IScannerCallback, ScanFilter, ScanFilterCondition,
    ScanFilterPattern, ScanResult, ScanSettings, ScanType,
};
use btstack::bluetooth_media::IBluetoothTelephony;
use btstack::socket_manager::{
    BluetoothServerSocket, BluetoothSocket, CallbackId, IBluetoothSocketManager,
    IBluetoothSocketManagerCallbacks, SocketId, SocketResult,
@@ -1817,3 +1818,40 @@ impl ISuspendCallback for ISuspendCallbackDBus {
    #[dbus_method("OnResumed")]
    fn on_resumed(&self, suspend_id: i32) {}
}

pub(crate) struct BluetoothTelephonyDBus {
    client_proxy: ClientDBusProxy,
}

impl BluetoothTelephonyDBus {
    pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothTelephonyDBus {
        BluetoothTelephonyDBus {
            client_proxy: ClientDBusProxy::new(
                conn.clone(),
                String::from("org.chromium.bluetooth"),
                make_object_path(index, "telephony"),
                String::from("org.chromium.bluetooth.BluetoothTelephony"),
            ),
        }
    }
}

#[generate_dbus_interface_client]
impl IBluetoothTelephony for BluetoothTelephonyDBus {
    #[dbus_method("SetNetworkAvailable")]
    fn set_network_available(&mut self, network_available: bool) {
        dbus_generated!()
    }
    #[dbus_method("SetRoaming")]
    fn set_roaming(&mut self, roaming: bool) {
        dbus_generated!()
    }
    #[dbus_method("SetSignalStrength")]
    fn set_signal_strength(&mut self, signal_strength: i32) -> bool {
        dbus_generated!()
    }
    #[dbus_method("SetBatteryLevel")]
    fn set_battery_level(&mut self, battery_level: i32) -> bool {
        dbus_generated!()
    }
}
+7 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ use crate::callbacks::{
use crate::command_handler::{CommandHandler, SocketSchedule};
use crate::dbus_iface::{
    BluetoothAdminDBus, BluetoothDBus, BluetoothGattDBus, BluetoothManagerDBus, BluetoothQADBus,
    BluetoothSocketManagerDBus, SuspendDBus,
    BluetoothSocketManagerDBus, BluetoothTelephonyDBus, SuspendDBus,
};
use crate::editor::AsyncEditor;
use bt_topshim::topstack;
@@ -89,6 +89,9 @@ pub(crate) struct ClientContext {
    /// Proxy for socket manager interface.
    pub(crate) socket_manager_dbus: Option<BluetoothSocketManagerDBus>,

    /// Proxy for Telephony interface.
    pub(crate) telephony_dbus: Option<BluetoothTelephonyDBus>,

    /// Channel to send actions to take in the foreground
    fg: mpsc::Sender<ForegroundActions>,

@@ -154,6 +157,7 @@ impl ClientContext {
            admin_dbus: None,
            suspend_dbus: None,
            socket_manager_dbus: None,
            telephony_dbus: None,
            fg: tx,
            dbus_connection,
            dbus_crossroads,
@@ -209,6 +213,8 @@ impl ClientContext {

        self.suspend_dbus = Some(SuspendDBus::new(conn.clone(), idx));

        self.telephony_dbus = Some(BluetoothTelephonyDBus::new(conn.clone(), idx));

        // Trigger callback registration in the foreground
        let fg = self.fg.clone();
        tokio::spawn(async move {
+33 −0
Original line number Diff line number Diff line
use btstack::bluetooth_media::IBluetoothTelephony;

use dbus_macros::{dbus_method, generate_dbus_exporter};

use dbus_projection::dbus_generated;

use crate::dbus_arg::DBusArg;

#[allow(dead_code)]
struct IBluetoothTelephonyDBus {}

#[generate_dbus_exporter(
    export_bluetooth_telephony_dbus_intf,
    "org.chromium.bluetooth.BluetoothTelephony"
)]
impl IBluetoothTelephony for IBluetoothTelephonyDBus {
    #[dbus_method("SetNetworkAvailable")]
    fn set_network_available(&mut self, network_available: bool) {
        dbus_generated!()
    }
    #[dbus_method("SetRoaming")]
    fn set_roaming(&mut self, roaming: bool) {
        dbus_generated!()
    }
    #[dbus_method("SetSignalStrength")]
    fn set_signal_strength(&mut self, signal_strength: i32) -> bool {
        dbus_generated!()
    }
    #[dbus_method("SetBatteryLevel")]
    fn set_battery_level(&mut self, battery_level: i32) -> bool {
        dbus_generated!()
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ mod iface_bluetooth;
mod iface_bluetooth_admin;
mod iface_bluetooth_gatt;
mod iface_bluetooth_media;
mod iface_bluetooth_telephony;
mod iface_logging;

const DBUS_SERVICE_NAME: &str = "org.chromium.bluetooth";
@@ -244,6 +245,12 @@ fn main() -> Result<(), Box<dyn Error>> {
            disconnect_watcher.clone(),
        );

        let telephony_iface = iface_bluetooth_telephony::export_bluetooth_telephony_dbus_intf(
            conn.clone(),
            &mut cr.lock().unwrap(),
            disconnect_watcher.clone(),
        );

        let battery_provider_manager_iface =
            iface_battery_provider_manager::export_battery_provider_manager_dbus_intf(
                conn.clone(),
@@ -288,11 +295,19 @@ fn main() -> Result<(), Box<dyn Error>> {
            &[media_iface],
            bluetooth_media.clone(),
        );

        cr.lock().unwrap().insert(
            make_object_name(adapter_index, "telephony"),
            &[telephony_iface],
            bluetooth_media.clone(),
        );

        cr.lock().unwrap().insert(
            make_object_name(adapter_index, "battery_provider_manager"),
            &[battery_provider_manager_iface],
            battery_provider_manager.clone(),
        );

        cr.lock().unwrap().insert(
            make_object_name(adapter_index, "battery_manager"),
            &[battery_manager_iface],
Loading