This is a preparation for publishing to crates.io. Changes include: - Add `servo-` prefixes to avoid name collisions on crates.io - Use `-` instead of `_` in package names. - Rename the crates to their original names in Cargo.toml, to keep the diff minimal - Rename `media` to `servo-media-thread` to avoid name collision with `servo-media` (originally from the media repository). This is an outcome of the previous discussion at [#general > Switch remaining git dependencies to crates.io](https://servo.zulipchat.com/#narrow/channel/263398-general/topic/Switch.20remaining.20git.20dependencies.20to.20crates.2Eio/with/576336288) Testing: This should be mostly covered by our CI, but some amount of breakage is to be expected, since some package names could still be referenced from scripts which are not tested or run in CI. [mach try run](https://github.com/jschwe/servo/actions/runs/22502945949) --------- Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
Bluetooth
Servo-specific APIs to access Bluetooth devices.
Bluetooth related code is located in bluetooth.rs.
Implementation
Underlying dependency crates:
- Android platform: blurdroid
- Linux platform: blurz
- macOS platform: blurmac
Fakeprefixed structures: blurmock
Empty prefixed structures are located in empty.rs.
Usage
Without the bluetooth-test feature
There are three supported platforms (Android, Linux, macOS), on other platforms we fall back to a default (Empty prefixed) implementation. Each enum (BluetoothAdapter, BluetoothDevice, etc.) will contain only one variant for each targeted platform. See the following BluetoothAdapter example:
Android:
pub enum BluetoothAdapter {
Android(Arc<BluetoothAdapterAndroid>),
}
Linux:
pub enum BluetoothAdapter {
Bluez(Arc<BluetoothAdapterBluez>),
}
macOS:
pub enum BluetoothAdapter {
Mac(Arc<BluetoothAdapterMac>),
}
Unsupported platforms:
pub enum BluetoothAdapter {
Empty(Arc<BluetoothAdapterEmpty>),
}
You will have a platform specific adapter, e.g. on Android target, BluetoothAdapter::init() will create a BluetoothAdapter::Android enum variant, which wraps an Arc<BluetoothAdapterAndroid>.
pub fn init() -> Result<BluetoothAdapter, Box<Error>> {
let blurdroid_adapter = try!(BluetoothAdapterAndroid::get_adapter());
Ok(BluetoothAdapter::Android(Arc::new(blurdroid_adapter)))
}
On each platform you can call the same functions to reach the same GATT hierarchy elements. The following code can access the same Bluetooth device on all supported platforms:
use device::{BluetoothAdapter, BluetoothDevice};
fn main() {
// Get the bluetooth adapter.
let adapter = BluetoothAdpater::init().expect("No bluetooth adapter found!");
// Get a device with the id 01:2A:00:4D:00:04 if it exists.
let device = adapter.get_device("01:2A:00:4D:00:04".to_owned() /*device address*/)
.expect("No bluetooth device found!");
}
With the bluetooth-test feature
Each enum (BluetoothAdapter, BluetoothDevice, etc.) will contain one variant of the three possible default target, and a Mock variant, which wraps a Fake structure.
Android:
pub enum BluetoothAdapter {
Android(Arc<BluetoothAdapterAndroid>),
Mock(Arc<FakeBluetoothAdapter>),
}
Linux:
pub enum BluetoothAdapter {
Bluez(Arc<BluetoothAdapterBluez>),
Mock(Arc<FakeBluetoothAdapter>),
}
macOS:
pub enum BluetoothAdapter {
Mac(Arc<BluetoothAdapterMac>),
Mock(Arc<FakeBluetoothAdapter>),
}
Unsupported platforms:
pub enum BluetoothAdapter {
Empty(Arc<BluetoothAdapterEmpty>),
Mock(Arc<FakeBluetoothAdapter>),
}
Beside the platform specific structures, you can create and access mock adapters, devices, services etc. These mock structures implements all the platform specific functions too. To create a mock GATT hierarchy, first you need to call the BluetoothAdapter::init_mock() function, insted of BluetoothAdapter::init().
use device::{BluetoothAdapter, BluetoothDevice};
use std::String;
// This function takes a BluetoothAdapter,
// and print the ids of the devices, which the adapter can find.
fn print_device_ids(adapter: &BluetoothAdpater) {
let devices = match adapter.get_devices().expect("No devices on the adapter!");
for device in devices {
println!("{:?}", device.get_id());
}
}
fn main() {
// This code uses a real adapter.
// Get the bluetooth adapter.
let adapter = BluetoothAdpater::init().expect("No bluetooth adapter found!");
// Get a device with the id 01:2A:00:4D:00:04 if it exists.
let device = adapter.get_device("01:2A:00:4D:00:04".to_owned() /*device address*/)
.expect("No bluetooth device found!");
// This code uses a mock adapter.
// Creating a mock adapter.
let mock_adapter = BluetoothAdpater::init_mock().unwrap();
// Creating a mock device.
let mock_device =
BluetoothDevice::create_mock_device(mock_adapter,
"device_id_string_goes_here".to_owned())
.unwrap();
// Changing its device_id.
let new_device_id = String::from("new_device_id_string".to_owned());
mock_device.set_id(new_device_id.clone());
// Calling the get_id function must return the last id we set.
assert_equals!(new_device_id, mock_device.get_id());
// Getting the mock_device with its id
// must return the same mock device object we created before.
assert_equals!(Some(mock_device),
mock_adapter.get_device(new_device_id.clone()).unwrap());
// The print_device_ids function accept real and mock adapters too.
print_device_ids(&adapter);
print_device_ids(&mock_adapter);
}
Calling a test function on a not Mock structure, will result an error with the message: Error! Test functions are not supported on real devices!.