mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
WebBluetooth Test API
This commit is contained in:
parent
4eec2c6ddc
commit
e15d54edfd
14 changed files with 701 additions and 14 deletions
|
@ -12,10 +12,11 @@ path = "lib.rs"
|
|||
[dependencies]
|
||||
bitflags = "0.7"
|
||||
bluetooth_traits = {path = "../bluetooth_traits"}
|
||||
device = {git = "https://github.com/servo/devices"}
|
||||
device = {git = "https://github.com/servo/devices", features = ["bluetooth-test"]}
|
||||
ipc-channel = "0.5"
|
||||
rand = "0.3"
|
||||
util = {path = "../util"}
|
||||
uuid = {version = "0.3.1", features = ["v4"]}
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
tinyfiledialogs = {git = "https://github.com/jdm/tinyfiledialogs"}
|
||||
|
|
|
@ -11,17 +11,17 @@ extern crate rand;
|
|||
#[cfg(target_os = "linux")]
|
||||
extern crate tinyfiledialogs;
|
||||
extern crate util;
|
||||
extern crate uuid;
|
||||
|
||||
pub mod test;
|
||||
|
||||
use bluetooth_traits::{BluetoothCharacteristicMsg, BluetoothCharacteristicsMsg};
|
||||
use bluetooth_traits::{BluetoothDescriptorMsg, BluetoothDescriptorsMsg};
|
||||
use bluetooth_traits::{BluetoothDeviceMsg, BluetoothError, BluetoothMethodMsg};
|
||||
use bluetooth_traits::{BluetoothResult, BluetoothServiceMsg, BluetoothServicesMsg};
|
||||
use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence, RequestDeviceoptions};
|
||||
use device::bluetooth::BluetoothAdapter;
|
||||
use device::bluetooth::BluetoothDevice;
|
||||
use device::bluetooth::BluetoothGATTCharacteristic;
|
||||
use device::bluetooth::BluetoothGATTDescriptor;
|
||||
use device::bluetooth::BluetoothGATTService;
|
||||
use device::bluetooth::{BluetoothAdapter, BluetoothDevice, BluetoothGATTCharacteristic};
|
||||
use device::bluetooth::{BluetoothGATTDescriptor, BluetoothGATTService};
|
||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||
use rand::Rng;
|
||||
use std::borrow::ToOwned;
|
||||
|
@ -33,6 +33,8 @@ use util::thread::spawn_named;
|
|||
|
||||
const ADAPTER_ERROR: &'static str = "No adapter found";
|
||||
|
||||
const ADAPTER_NOT_POWERED_ERROR: &'static str = "Bluetooth adapter not powered";
|
||||
|
||||
// A transaction not completed within 30 seconds shall time out. Such a transaction shall be considered to have failed.
|
||||
// https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=286439 (Vol. 3, page 480)
|
||||
const MAXIMUM_TRANSACTION_TIME: u8 = 30;
|
||||
|
@ -71,7 +73,12 @@ macro_rules! return_if_cached(
|
|||
macro_rules! get_adapter_or_return_error(
|
||||
($bl_manager:expr, $sender:expr) => (
|
||||
match $bl_manager.get_or_create_adapter() {
|
||||
Some(adapter) => adapter,
|
||||
Some(adapter) => {
|
||||
if !adapter.is_powered().unwrap_or(false) {
|
||||
return drop($sender.send(Err(BluetoothError::Type(ADAPTER_NOT_POWERED_ERROR.to_string()))))
|
||||
}
|
||||
adapter
|
||||
},
|
||||
None => return drop($sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
|
||||
}
|
||||
);
|
||||
|
@ -155,6 +162,13 @@ fn matches_filters(device: &BluetoothDevice, filters: &BluetoothScanfilterSequen
|
|||
return filters.iter().any(|f| matches_filter(device, f))
|
||||
}
|
||||
|
||||
fn is_mock_adapter(adapter: &BluetoothAdapter) -> bool {
|
||||
match adapter {
|
||||
&BluetoothAdapter::Mock(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BluetoothManager {
|
||||
receiver: IpcReceiver<BluetoothMethodMsg>,
|
||||
adapter: Option<BluetoothAdapter>,
|
||||
|
@ -228,6 +242,9 @@ impl BluetoothManager {
|
|||
BluetoothMethodMsg::WriteValue(id, value, sender) => {
|
||||
self.write_value(id, value, sender)
|
||||
},
|
||||
BluetoothMethodMsg::Test(data_set_name, sender) => {
|
||||
self.test(data_set_name, sender)
|
||||
}
|
||||
BluetoothMethodMsg::Exit => {
|
||||
break
|
||||
},
|
||||
|
@ -235,13 +252,46 @@ impl BluetoothManager {
|
|||
}
|
||||
}
|
||||
|
||||
// Test
|
||||
|
||||
fn test(&mut self, data_set_name: String, sender: IpcSender<BluetoothResult<()>>) {
|
||||
self.address_to_id.clear();
|
||||
self.service_to_device.clear();
|
||||
self.characteristic_to_service.clear();
|
||||
self.descriptor_to_characteristic.clear();
|
||||
self.cached_devices.clear();
|
||||
self.cached_services.clear();
|
||||
self.cached_characteristics.clear();
|
||||
self.cached_descriptors.clear();
|
||||
self.allowed_services.clear();
|
||||
self.adapter = BluetoothAdapter::init_mock().ok();
|
||||
match test::test(self, data_set_name) {
|
||||
Ok(_) => {
|
||||
let _ = sender.send(Ok(()));
|
||||
},
|
||||
Err(error) => {
|
||||
let _ = sender.send(Err(BluetoothError::Type(error.description().to_owned())));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Adapter
|
||||
|
||||
fn get_or_create_adapter(&mut self) -> Option<BluetoothAdapter> {
|
||||
pub fn get_or_create_adapter(&mut self) -> Option<BluetoothAdapter> {
|
||||
let adapter_valid = self.adapter.as_ref().map_or(false, |a| a.get_address().is_ok());
|
||||
if !adapter_valid {
|
||||
self.adapter = BluetoothAdapter::init().ok();
|
||||
}
|
||||
|
||||
let adapter = match self.adapter.as_ref() {
|
||||
Some(adapter) => adapter,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
if is_mock_adapter(adapter) && !adapter.is_present().unwrap_or(false) {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.adapter.clone()
|
||||
}
|
||||
|
||||
|
@ -270,7 +320,16 @@ impl BluetoothManager {
|
|||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn select_device(&mut self, devices: Vec<BluetoothDevice>) -> Option<String> {
|
||||
fn select_device(&mut self, devices: Vec<BluetoothDevice>, adapter: &BluetoothAdapter) -> Option<String> {
|
||||
if is_mock_adapter(adapter) {
|
||||
for device in devices {
|
||||
if let Ok(address) = device.get_address() {
|
||||
return Some(address);
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut dialog_rows: Vec<String> = vec!();
|
||||
for device in devices {
|
||||
dialog_rows.extend_from_slice(&[device.get_address().unwrap_or("".to_string()),
|
||||
|
@ -291,7 +350,7 @@ impl BluetoothManager {
|
|||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn select_device(&mut self, devices: Vec<BluetoothDevice>) -> Option<String> {
|
||||
fn select_device(&mut self, devices: Vec<BluetoothDevice>, _adapter: &BluetoothAdapter) -> Option<String> {
|
||||
for device in devices {
|
||||
if let Ok(address) = device.get_address() {
|
||||
return Some(address);
|
||||
|
@ -475,7 +534,9 @@ impl BluetoothManager {
|
|||
let mut adapter = get_adapter_or_return_error!(self, sender);
|
||||
if let Ok(ref session) = adapter.create_discovery_session() {
|
||||
if session.start_discovery().is_ok() {
|
||||
thread::sleep(Duration::from_millis(DISCOVERY_TIMEOUT_MS));
|
||||
if !is_mock_adapter(&adapter) {
|
||||
thread::sleep(Duration::from_millis(DISCOVERY_TIMEOUT_MS));
|
||||
}
|
||||
}
|
||||
let _ = session.stop_discovery();
|
||||
}
|
||||
|
@ -492,7 +553,7 @@ impl BluetoothManager {
|
|||
}
|
||||
|
||||
// Step 8.
|
||||
if let Some(address) = self.select_device(matched_devices) {
|
||||
if let Some(address) = self.select_device(matched_devices, &adapter) {
|
||||
let device_id = match self.address_to_id.get(&address) {
|
||||
Some(id) => id.clone(),
|
||||
None => return drop(sender.send(Err(BluetoothError::NotFound))),
|
||||
|
@ -528,7 +589,12 @@ impl BluetoothManager {
|
|||
for _ in 0..MAXIMUM_TRANSACTION_TIME {
|
||||
match d.is_connected().unwrap_or(false) {
|
||||
true => return drop(sender.send(Ok(true))),
|
||||
false => thread::sleep(Duration::from_millis(CONNECTION_TIMEOUT_MS)),
|
||||
false => {
|
||||
if is_mock_adapter(&adapter) {
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_millis(CONNECTION_TIMEOUT_MS));
|
||||
},
|
||||
}
|
||||
}
|
||||
return drop(sender.send(Err(BluetoothError::Network)));
|
||||
|
|
501
components/bluetooth/test.rs
Normal file
501
components/bluetooth/test.rs
Normal file
|
@ -0,0 +1,501 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use BluetoothManager;
|
||||
use device::bluetooth::{BluetoothAdapter, BluetoothDevice};
|
||||
use device::bluetooth::{BluetoothGATTCharacteristic, BluetoothGATTDescriptor, BluetoothGATTService};
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::string::String;
|
||||
use uuid::Uuid;
|
||||
|
||||
thread_local!(pub static CACHED_IDS: RefCell<HashSet<Uuid>> = RefCell::new(HashSet::new()));
|
||||
|
||||
const ADAPTER_ERROR: &'static str = "No adapter found";
|
||||
const WRONG_DATA_SET_ERROR: &'static str = "Wrong data set name was provided";
|
||||
const READ_FLAG: &'static str = "read";
|
||||
const WRITE_FLAG: &'static str = "write";
|
||||
|
||||
// Adapter names
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=65
|
||||
const NOT_PRESENT_ADAPTER: &'static str = "NotPresentAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=83
|
||||
const NOT_POWERED_ADAPTER: &'static str = "NotPoweredAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=118
|
||||
const EMPTY_ADAPTER: &'static str = "EmptyAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=126
|
||||
const GLUCOSE_HEART_RATE_ADAPTER: &'static str = "GlucoseHeartRateAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=135
|
||||
const UNICODE_DEVICE_ADAPTER: &'static str = "UnicodeDeviceAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=205
|
||||
const MISSING_SERVICE_HEART_RATE_ADAPTER: &'static str = "MissingServiceHeartRateAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=219
|
||||
const MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER: &'static str = "MissingCharacteristicHeartRateAdapter";
|
||||
const MISSING_DESCRIPTOR_HEART_RATE_ADAPTER: &'static str = "MissingDescriptorHeartRateAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=234
|
||||
const HEART_RATE_ADAPTER: &'static str = "HeartRateAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=250
|
||||
const EMPTY_NAME_HEART_RATE_ADAPTER: &'static str = "EmptyNameHeartRateAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=267
|
||||
const NO_NAME_HEART_RATE_ADAPTER: &'static str = "NoNameHeartRateAdapter";
|
||||
// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=284
|
||||
const TWO_HEART_RATE_SERVICES_ADAPTER: &'static str = "TwoHeartRateServicesAdapter";
|
||||
const BLACKLIST_TEST_ADAPTER: &'static str = "BlacklistTestAdapter";
|
||||
|
||||
// Device names
|
||||
const CONNECTABLE_DEVICE_NAME: &'static str = "Connectable Device";
|
||||
const EMPTY_DEVICE_NAME: &'static str = "";
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/tests.html#glucosedevice
|
||||
const GLUCOSE_DEVICE_NAME: &'static str = "Glucose Device";
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/tests.html#heartratedevice
|
||||
const HEART_RATE_DEVICE_NAME: &'static str = "Heart Rate Device";
|
||||
const UNICODE_DEVICE_NAME: &'static str = "❤❤❤❤❤❤❤❤❤";
|
||||
|
||||
// Device addresses
|
||||
const CONNECTABLE_DEVICE_ADDRESS: &'static str = "00:00:00:00:00:04";
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/tests.html#glucosedevice
|
||||
const GLUCOSE_DEVICE_ADDRESS: &'static str = "00:00:00:00:00:02";
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/tests.html#heartratedevice
|
||||
const HEART_RATE_DEVICE_ADDRESS: &'static str = "00:00:00:00:00:03";
|
||||
const UNICODE_DEVICE_ADDRESS: &'static str = "00:00:00:00:00:01";
|
||||
|
||||
// Service UUIDs
|
||||
const BLACKLIST_TEST_SERVICE_UUID: &'static str = "611c954a-263b-4f4a-aab6-01ddb953f985";
|
||||
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.device_information.xml
|
||||
const DEVICE_INFORMATION_UUID: &'static str = "0000180a-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.generic_access.xml
|
||||
const GENERIC_ACCESS_SERVICE_UUID: &'static str = "00001800-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.glucose.xml
|
||||
const GLUCOSE_SERVICE_UUID: &'static str = "00001808-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.heart_rate.xml
|
||||
const HEART_RATE_SERVICE_UUID: &'static str = "0000180d-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/
|
||||
// viewer?attributeXmlFile=org.bluetooth.service.human_interface_device.xml
|
||||
const HUMAN_INTERFACE_DEVICE_SERVICE_UUID: &'static str = "00001812-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.tx_power.xml
|
||||
const TX_POWER_SERVICE_UUID: &'static str = "00001804-0000-1000-8000-00805f9b34fb";
|
||||
|
||||
// Characteristic UUIDs
|
||||
const BLACKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID: &'static str = "bad1c9a2-9a5b-4015-8b60-1579bbbf2135";
|
||||
// https://www.bluetooth.com/specifications/gatt/
|
||||
// viewer?attributeXmlFile=org.bluetooth.characteristic.body_sensor_location.xml
|
||||
const BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID: &'static str = "00002a38-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/
|
||||
// viewer?attributeXmlFile=org.bluetooth.characteristic.gap.device_name.xml
|
||||
const DEVICE_NAME_CHARACTERISTIC_UUID: &'static str = "00002a00-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/
|
||||
// viewer?attributeXmlFile=org.bluetooth.characteristic.heart_rate_measurement.xml
|
||||
const HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID: &'static str = "00002a37-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/
|
||||
// viewer?attributeXmlFile=org.bluetooth.characteristic.gap.peripheral_privacy_flag.xml
|
||||
const PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID: &'static str = "00002a02-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/
|
||||
// viewer?attributeXmlFile=org.bluetooth.characteristic.serial_number_string.xml
|
||||
const SERIAL_NUMBER_STRING_UUID: &'static str = "00002a25-0000-1000-8000-00805f9b34fb";
|
||||
|
||||
// Descriptor UUIDs
|
||||
const BLACKLIST_EXCLUDE_READS_DESCRIPTOR_UUID: &'static str = "aaaaaaaa-aaaa-1181-0510-810819516110";
|
||||
const BLACKLIST_DESCRIPTOR_UUID: &'static str = "07711111-6104-0970-7011-1107105110aaa";
|
||||
// https://www.bluetooth.com/specifications/gatt/
|
||||
// viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_user_description.xml
|
||||
const CHARACTERISTIC_USER_DESCRIPTION_UUID: &'static str = "00002901-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/
|
||||
// viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
|
||||
const CLIENT_CHARACTERISTIC_CONFIGURATION_UUID: &'static str = "00002902-0000-1000-8000-00805f9b34fb";
|
||||
// https://www.bluetooth.com/specifications/gatt/
|
||||
// viewer?attributeXmlFile=org.bluetooth.descriptor.number_of_digitals.xml
|
||||
const NUMBER_OF_DIGITALS_UUID: &'static str = "00002909-0000-1000-8000-00805f9b34fb";
|
||||
|
||||
const HEART_RATE_DEVICE_NAME_DESCRIPTION: &'static str = "The name of this device.";
|
||||
|
||||
fn generate_id() -> Uuid {
|
||||
let mut id = Uuid::nil();
|
||||
let mut generated = false;
|
||||
while !generated {
|
||||
id = Uuid::new_v4();
|
||||
CACHED_IDS.with(|cache|
|
||||
if !cache.borrow().contains(&id) {
|
||||
cache.borrow_mut().insert(id.clone());
|
||||
generated = true;
|
||||
}
|
||||
);
|
||||
}
|
||||
id
|
||||
}
|
||||
|
||||
// Set the adapter's name, is_powered and is_discoverable attributes
|
||||
fn set_adapter(adapter: &BluetoothAdapter, adapter_name: String) -> Result<(), Box<Error>> {
|
||||
try!(adapter.set_name(adapter_name));
|
||||
try!(adapter.set_powered(true));
|
||||
try!(adapter.set_discoverable(true));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Create Device
|
||||
fn create_device(adapter: &BluetoothAdapter,
|
||||
name: String,
|
||||
address: String)
|
||||
-> Result<BluetoothDevice, Box<Error>> {
|
||||
let device = try!(BluetoothDevice::create_mock_device(adapter.clone(), generate_id().to_string()));
|
||||
try!(device.set_name(Some(name)));
|
||||
try!(device.set_address(address));
|
||||
try!(device.set_connectable(true));
|
||||
Ok(device)
|
||||
}
|
||||
|
||||
// Create Device with UUIDs
|
||||
fn create_device_with_uuids(adapter: &BluetoothAdapter,
|
||||
name: String,
|
||||
address: String,
|
||||
uuids: Vec<String>)
|
||||
-> Result<BluetoothDevice, Box<Error>> {
|
||||
let device = try!(create_device(adapter, name, address));
|
||||
try!(device.set_uuids(uuids));
|
||||
Ok(device)
|
||||
}
|
||||
|
||||
// Create Service
|
||||
fn create_service(device: &BluetoothDevice,
|
||||
uuid: String)
|
||||
-> Result<BluetoothGATTService, Box<Error>> {
|
||||
let service = try!(BluetoothGATTService::create_mock_service(device.clone(), generate_id().to_string()));
|
||||
try!(service.set_uuid(uuid));
|
||||
Ok(service)
|
||||
}
|
||||
|
||||
// Create Characteristic
|
||||
fn create_characteristic(service: &BluetoothGATTService,
|
||||
uuid: String)
|
||||
-> Result<BluetoothGATTCharacteristic, Box<Error>> {
|
||||
let characteristic =
|
||||
try!(BluetoothGATTCharacteristic::create_mock_characteristic(service.clone(), generate_id().to_string()));
|
||||
try!(characteristic.set_uuid(uuid));
|
||||
Ok(characteristic)
|
||||
}
|
||||
|
||||
// Create Characteristic with value
|
||||
fn create_characteristic_with_value(service: &BluetoothGATTService,
|
||||
uuid: String,
|
||||
value: Vec<u8>)
|
||||
-> Result<BluetoothGATTCharacteristic, Box<Error>> {
|
||||
let characteristic = try!(create_characteristic(service, uuid));
|
||||
try!(characteristic.set_value(value));
|
||||
Ok(characteristic)
|
||||
}
|
||||
|
||||
// Create Descriptor
|
||||
fn create_descriptor(characteristic: &BluetoothGATTCharacteristic,
|
||||
uuid: String)
|
||||
-> Result<BluetoothGATTDescriptor, Box<Error>> {
|
||||
let descriptor =
|
||||
try!(BluetoothGATTDescriptor::create_mock_descriptor(characteristic.clone(), generate_id().to_string()));
|
||||
try!(descriptor.set_uuid(uuid));
|
||||
Ok(descriptor)
|
||||
}
|
||||
|
||||
// Create Descriptor with value
|
||||
fn create_descriptor_with_value(characteristic: &BluetoothGATTCharacteristic,
|
||||
uuid: String,
|
||||
value: Vec<u8>)
|
||||
-> Result<BluetoothGATTDescriptor, Box<Error>> {
|
||||
let descriptor = try!(create_descriptor(characteristic, uuid));
|
||||
try!(descriptor.set_value(value));
|
||||
Ok(descriptor)
|
||||
}
|
||||
|
||||
fn create_heart_rate_service(device: &BluetoothDevice,
|
||||
empty: bool)
|
||||
-> Result<BluetoothGATTService, Box<Error>> {
|
||||
// Heart Rate Service
|
||||
let heart_rate_service = try!(create_service(device, HEART_RATE_SERVICE_UUID.to_owned()));
|
||||
|
||||
if empty {
|
||||
return Ok(heart_rate_service)
|
||||
}
|
||||
|
||||
// Heart Rate Measurement Characteristic
|
||||
let _heart_rate_measurement_characteristic =
|
||||
try!(create_characteristic_with_value(&heart_rate_service,
|
||||
HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(),
|
||||
vec![0]));
|
||||
|
||||
// Body Sensor Location Characteristic 1
|
||||
let body_sensor_location_characteristic_1 =
|
||||
try!(create_characteristic_with_value(&heart_rate_service,
|
||||
BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
|
||||
vec![49]));
|
||||
try!(body_sensor_location_characteristic_1.set_flags(vec![READ_FLAG.to_string()]));
|
||||
|
||||
// Body Sensor Location Characteristic 2
|
||||
let body_sensor_location_characteristic_2 =
|
||||
try!(create_characteristic_with_value(&heart_rate_service,
|
||||
BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
|
||||
vec![50]));
|
||||
try!(body_sensor_location_characteristic_2.set_flags(vec![READ_FLAG.to_string()]));
|
||||
Ok(heart_rate_service)
|
||||
}
|
||||
|
||||
fn create_generic_access_service(device: &BluetoothDevice,
|
||||
empty: bool)
|
||||
-> Result<BluetoothGATTService, Box<Error>> {
|
||||
// Generic Access Service
|
||||
let generic_access_service =
|
||||
try!(create_service(device, GENERIC_ACCESS_SERVICE_UUID.to_owned()));
|
||||
|
||||
if empty {
|
||||
return Ok(generic_access_service)
|
||||
}
|
||||
|
||||
// Device Name Characteristic
|
||||
let device_name_characteristic =
|
||||
try!(create_characteristic_with_value(&generic_access_service,
|
||||
DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(),
|
||||
HEART_RATE_DEVICE_NAME.as_bytes().to_vec()));
|
||||
try!(device_name_characteristic.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
|
||||
|
||||
// Number of Digitals descriptor
|
||||
let number_of_digitals_descriptor_1 =
|
||||
try!(create_descriptor_with_value(&device_name_characteristic,
|
||||
NUMBER_OF_DIGITALS_UUID.to_owned(),
|
||||
vec![49]));
|
||||
try!(number_of_digitals_descriptor_1.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
|
||||
|
||||
let number_of_digitals_descriptor_2 =
|
||||
try!(create_descriptor_with_value(&device_name_characteristic,
|
||||
NUMBER_OF_DIGITALS_UUID.to_owned(),
|
||||
vec![50]));
|
||||
try!(number_of_digitals_descriptor_2.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
|
||||
|
||||
// Characteristic User Description Descriptor
|
||||
let _characteristic_user_description =
|
||||
try!(create_descriptor_with_value(&device_name_characteristic,
|
||||
CHARACTERISTIC_USER_DESCRIPTION_UUID.to_owned(),
|
||||
HEART_RATE_DEVICE_NAME_DESCRIPTION.as_bytes().to_vec()));
|
||||
|
||||
// Client Characteristic Configuration descriptor
|
||||
let _client_characteristic_configuration =
|
||||
try!(create_descriptor_with_value(&device_name_characteristic,
|
||||
CLIENT_CHARACTERISTIC_CONFIGURATION_UUID.to_owned(),
|
||||
vec![0]));
|
||||
|
||||
// Peripheral Privacy Flag Characteristic
|
||||
let peripheral_privacy_flag_characteristic =
|
||||
try!(create_characteristic(&generic_access_service, PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned()));
|
||||
try!(peripheral_privacy_flag_characteristic
|
||||
.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
|
||||
Ok(generic_access_service)
|
||||
}
|
||||
|
||||
// Create Heart Rate Device
|
||||
fn create_heart_rate_device(adapter: &BluetoothAdapter,
|
||||
empty: bool)
|
||||
-> Result<BluetoothDevice, Box<Error>> {
|
||||
// Heart Rate Device
|
||||
let heart_rate_device =
|
||||
try!(create_device_with_uuids(adapter,
|
||||
HEART_RATE_DEVICE_NAME.to_owned(),
|
||||
HEART_RATE_DEVICE_ADDRESS.to_owned(),
|
||||
vec![GENERIC_ACCESS_SERVICE_UUID.to_owned(),
|
||||
HEART_RATE_SERVICE_UUID.to_owned()]));
|
||||
|
||||
if empty {
|
||||
return Ok(heart_rate_device);
|
||||
}
|
||||
|
||||
// Generic Access Service
|
||||
let _generic_access_service = try!(create_generic_access_service(&heart_rate_device, false));
|
||||
|
||||
// Heart Rate Service
|
||||
let _heart_rate_service = try!(create_heart_rate_service(&heart_rate_device, false));
|
||||
|
||||
Ok(heart_rate_device)
|
||||
}
|
||||
|
||||
fn create_missing_characterisitc_heart_rate_device(adapter: &BluetoothAdapter) -> Result<(), Box<Error>> {
|
||||
let heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
|
||||
|
||||
let _generic_access_service_empty = try!(create_generic_access_service(&heart_rate_device_empty, true));
|
||||
|
||||
let _heart_rate_service_empty = try!(create_heart_rate_service(&heart_rate_device_empty, true));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_missing_descriptor_heart_rate_device(adapter: &BluetoothAdapter) -> Result<(), Box<Error>> {
|
||||
let heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
|
||||
|
||||
let generic_access_service_empty = try!(create_generic_access_service(&heart_rate_device_empty, true));
|
||||
|
||||
let _device_name_characteristic =
|
||||
try!(create_characteristic_with_value(&generic_access_service_empty,
|
||||
DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(),
|
||||
HEART_RATE_DEVICE_NAME.as_bytes().to_vec()));
|
||||
|
||||
let peripheral_privacy_flag_characteristic =
|
||||
try!(create_characteristic(&generic_access_service_empty,
|
||||
PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned()));
|
||||
try!(peripheral_privacy_flag_characteristic.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
|
||||
|
||||
let _heart_rate_service = try!(create_heart_rate_service(&heart_rate_device_empty, false));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_two_heart_rate_services_device(adapter: &BluetoothAdapter) -> Result<(), Box<Error>> {
|
||||
let heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
|
||||
|
||||
try!(heart_rate_device_empty.set_uuids(vec![GENERIC_ACCESS_SERVICE_UUID.to_owned(),
|
||||
HEART_RATE_SERVICE_UUID.to_owned(),
|
||||
HEART_RATE_SERVICE_UUID.to_owned()]));
|
||||
|
||||
let _generic_access_service = try!(create_generic_access_service(&heart_rate_device_empty, false));
|
||||
|
||||
let heart_rate_service_empty_1 = try!(create_heart_rate_service(&heart_rate_device_empty, true));
|
||||
|
||||
let heart_rate_service_empty_2 = try!(create_heart_rate_service(&heart_rate_device_empty, true));
|
||||
|
||||
let _heart_rate_measurement_characteristic =
|
||||
try!(create_characteristic_with_value(&heart_rate_service_empty_1,
|
||||
HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(),
|
||||
vec![0]));
|
||||
|
||||
let _body_sensor_location_characteristic_1 =
|
||||
try!(create_characteristic_with_value(&heart_rate_service_empty_1,
|
||||
BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
|
||||
vec![49]));
|
||||
|
||||
let _body_sensor_location_characteristic_2 =
|
||||
try!(create_characteristic_with_value(&heart_rate_service_empty_2,
|
||||
BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
|
||||
vec![50]));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_blacklisted_device(adapter: &BluetoothAdapter) -> Result<(), Box<Error>> {
|
||||
let connectable_device =
|
||||
try!(create_device_with_uuids(adapter,
|
||||
CONNECTABLE_DEVICE_NAME.to_owned(),
|
||||
CONNECTABLE_DEVICE_ADDRESS.to_owned(),
|
||||
vec![BLACKLIST_TEST_SERVICE_UUID.to_owned(),
|
||||
DEVICE_INFORMATION_UUID.to_owned(),
|
||||
GENERIC_ACCESS_SERVICE_UUID.to_owned(),
|
||||
HEART_RATE_SERVICE_UUID.to_owned(),
|
||||
HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned()]));
|
||||
|
||||
let blacklist_test_service = try!(create_service(&connectable_device, BLACKLIST_TEST_SERVICE_UUID.to_owned()));
|
||||
|
||||
let blacklist_exclude_reads_characteristic =
|
||||
try!(create_characteristic(&blacklist_test_service,
|
||||
BLACKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID.to_owned()));
|
||||
try!(blacklist_exclude_reads_characteristic
|
||||
.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
|
||||
|
||||
let _blacklist_exclude_reads_descriptor =
|
||||
try!(create_descriptor_with_value(&blacklist_exclude_reads_characteristic,
|
||||
BLACKLIST_EXCLUDE_READS_DESCRIPTOR_UUID.to_owned(),
|
||||
vec![54; 3]));
|
||||
|
||||
let _blacklist_descriptor =
|
||||
try!(create_descriptor_with_value(&blacklist_exclude_reads_characteristic,
|
||||
BLACKLIST_DESCRIPTOR_UUID.to_owned(),
|
||||
vec![54; 3]));
|
||||
|
||||
let device_information_service = try!(create_service(&connectable_device, DEVICE_INFORMATION_UUID.to_owned()));
|
||||
|
||||
let _serial_number_string_characteristic =
|
||||
try!(create_characteristic(&device_information_service, SERIAL_NUMBER_STRING_UUID.to_owned()));
|
||||
|
||||
let _generic_access_service = try!(create_generic_access_service(&connectable_device, false));
|
||||
|
||||
let _heart_rate_service = try!(create_heart_rate_service(&connectable_device, false));
|
||||
|
||||
let _human_interface_device_service =
|
||||
try!(create_service(&connectable_device, HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn test(manager: &mut BluetoothManager, data_set_name: String) -> Result<(), Box<Error>> {
|
||||
let may_existing_adapter = manager.get_or_create_adapter();
|
||||
let adapter = match may_existing_adapter.as_ref() {
|
||||
Some(adapter) => adapter,
|
||||
None => return Err(Box::from(ADAPTER_ERROR.to_string())),
|
||||
};
|
||||
match data_set_name.as_str() {
|
||||
NOT_PRESENT_ADAPTER => {
|
||||
try!(set_adapter(adapter, NOT_PRESENT_ADAPTER.to_owned()));
|
||||
try!(adapter.set_present(false));
|
||||
},
|
||||
NOT_POWERED_ADAPTER => {
|
||||
try!(set_adapter(adapter, NOT_POWERED_ADAPTER.to_owned()));
|
||||
try!(adapter.set_powered(false));
|
||||
},
|
||||
EMPTY_ADAPTER => {
|
||||
try!(set_adapter(adapter, EMPTY_ADAPTER.to_owned()));
|
||||
},
|
||||
GLUCOSE_HEART_RATE_ADAPTER => {
|
||||
try!(set_adapter(adapter, GLUCOSE_HEART_RATE_ADAPTER.to_owned()));
|
||||
|
||||
let _glucose_devie = try!(create_device_with_uuids(adapter,
|
||||
GLUCOSE_DEVICE_NAME.to_owned(),
|
||||
GLUCOSE_DEVICE_ADDRESS.to_owned(),
|
||||
vec![GLUCOSE_SERVICE_UUID.to_owned(),
|
||||
TX_POWER_SERVICE_UUID.to_owned()]));
|
||||
|
||||
let _heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
|
||||
},
|
||||
UNICODE_DEVICE_ADAPTER => {
|
||||
try!(set_adapter(adapter, UNICODE_DEVICE_ADAPTER.to_owned()));
|
||||
|
||||
let _unicode_device = try!(create_device(adapter,
|
||||
UNICODE_DEVICE_NAME.to_owned(),
|
||||
UNICODE_DEVICE_ADDRESS.to_owned()));
|
||||
},
|
||||
MISSING_SERVICE_HEART_RATE_ADAPTER => {
|
||||
try!(set_adapter(adapter, MISSING_SERVICE_HEART_RATE_ADAPTER.to_owned()));
|
||||
|
||||
let _heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
|
||||
},
|
||||
MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER => {
|
||||
try!(set_adapter(adapter, MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER.to_owned()));
|
||||
|
||||
let _ = try!(create_missing_characterisitc_heart_rate_device(adapter));
|
||||
},
|
||||
MISSING_DESCRIPTOR_HEART_RATE_ADAPTER => {
|
||||
try!(set_adapter(adapter, MISSING_DESCRIPTOR_HEART_RATE_ADAPTER.to_owned()));
|
||||
|
||||
let _ = try!(create_missing_descriptor_heart_rate_device(adapter));
|
||||
},
|
||||
HEART_RATE_ADAPTER => {
|
||||
try!(set_adapter(adapter, HEART_RATE_ADAPTER.to_owned()));
|
||||
|
||||
let _heart_rate_device = try!(create_heart_rate_device(adapter, false));
|
||||
},
|
||||
EMPTY_NAME_HEART_RATE_ADAPTER => {
|
||||
try!(set_adapter(adapter, EMPTY_NAME_HEART_RATE_ADAPTER.to_owned()));
|
||||
|
||||
let heart_rate_device = try!(create_heart_rate_device(adapter, false));
|
||||
try!(heart_rate_device.set_name(Some(EMPTY_DEVICE_NAME.to_owned())));
|
||||
},
|
||||
NO_NAME_HEART_RATE_ADAPTER => {
|
||||
try!(set_adapter(adapter, NO_NAME_HEART_RATE_ADAPTER.to_owned()));
|
||||
|
||||
let heart_rate_device = try!(create_heart_rate_device(adapter, false));
|
||||
try!(heart_rate_device.set_name(None));
|
||||
},
|
||||
TWO_HEART_RATE_SERVICES_ADAPTER => {
|
||||
try!(set_adapter(adapter, TWO_HEART_RATE_SERVICES_ADAPTER.to_owned()));
|
||||
|
||||
let _ = try!(create_two_heart_rate_services_device(adapter));
|
||||
},
|
||||
BLACKLIST_TEST_ADAPTER => {
|
||||
try!(set_adapter(adapter, BLACKLIST_TEST_ADAPTER.to_owned()));
|
||||
|
||||
let _ = try!(create_blacklisted_device(adapter));
|
||||
},
|
||||
_ => return Err(Box::from(WRONG_DATA_SET_ERROR.to_string())),
|
||||
}
|
||||
return Ok(());
|
||||
}
|
|
@ -86,5 +86,6 @@ pub enum BluetoothMethodMsg {
|
|||
GetDescriptors(String, Option<String>, IpcSender<BluetoothResult<BluetoothDescriptorsMsg>>),
|
||||
ReadValue(String, IpcSender<BluetoothResult<Vec<u8>>>),
|
||||
WriteValue(String, Vec<u8>, IpcSender<BluetoothResult<bool>>),
|
||||
Test(String, IpcSender<BluetoothResult<()>>),
|
||||
Exit,
|
||||
}
|
||||
|
|
|
@ -399,6 +399,7 @@ pub mod testbinding;
|
|||
pub mod testbindingiterable;
|
||||
pub mod testbindingpairiterable;
|
||||
pub mod testbindingproxy;
|
||||
pub mod testrunner;
|
||||
pub mod text;
|
||||
pub mod textdecoder;
|
||||
pub mod textencoder;
|
||||
|
|
53
components/script/dom/testrunner.rs
Normal file
53
components/script/dom/testrunner.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use bluetooth_traits::BluetoothMethodMsg;
|
||||
use dom::bindings::codegen::Bindings::TestRunnerBinding;
|
||||
use dom::bindings::codegen::Bindings::TestRunnerBinding::TestRunnerMethods;
|
||||
use dom::bindings::error::{Error, ErrorResult};
|
||||
use dom::bindings::js::Root;
|
||||
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
|
||||
use dom::bindings::str::DOMString;
|
||||
use dom::globalscope::GlobalScope;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/tests#test-runner
|
||||
#[dom_struct]
|
||||
pub struct TestRunner {
|
||||
reflector_: Reflector,
|
||||
}
|
||||
|
||||
impl TestRunner {
|
||||
pub fn new_inherited() -> TestRunner {
|
||||
TestRunner {
|
||||
reflector_: Reflector::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(global: &GlobalScope) -> Root<TestRunner> {
|
||||
reflect_dom_object(box TestRunner::new_inherited(),
|
||||
global,
|
||||
TestRunnerBinding::Wrap)
|
||||
}
|
||||
|
||||
fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
|
||||
self.global().as_window().bluetooth_thread()
|
||||
}
|
||||
}
|
||||
|
||||
impl TestRunnerMethods for TestRunner {
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/tests#setBluetoothMockDataSet
|
||||
fn SetBluetoothMockDataSet(&self, dataSetName: DOMString) -> ErrorResult {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.get_bluetooth_thread().send(BluetoothMethodMsg::Test(String::from(dataSetName), sender)).unwrap();
|
||||
match receiver.recv().unwrap().into() {
|
||||
Ok(()) => {
|
||||
Ok(())
|
||||
},
|
||||
Err(error) => {
|
||||
Err(Error::from(error))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
16
components/script/dom/webidls/TestRunner.webidl
Normal file
16
components/script/dom/webidls/TestRunner.webidl
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/tests#test-runner
|
||||
|
||||
// callback BluetoothManualChooserEventsCallback = void(sequence<DOMString> events);
|
||||
|
||||
[Pref="dom.bluetooth.testing.enabled", Exposed=Window]
|
||||
interface TestRunner {
|
||||
[Throws]
|
||||
void setBluetoothMockDataSet(DOMString dataSetName);
|
||||
// void setBluetoothManualChooser();
|
||||
// void getBluetoothManualChooserEvents(BluetoothManualChooserEventsCallback callback);
|
||||
// void sendBluetoothManualChooserEvent(DOMString event, DOMString argument);
|
||||
};
|
|
@ -185,3 +185,10 @@ Window implements WindowLocalStorage;
|
|||
|
||||
// http://w3c.github.io/animation-timing/#framerequestcallback
|
||||
callback FrameRequestCallback = void (DOMHighResTimeStamp time);
|
||||
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/tests#test-interfaces
|
||||
partial interface Window {
|
||||
[Pref="dom.bluetooth.testing.enabled", Exposed=Window]
|
||||
readonly attribute TestRunner testRunner;
|
||||
//readonly attribute EventSender eventSender;
|
||||
};
|
||||
|
|
|
@ -45,6 +45,7 @@ use dom::performance::Performance;
|
|||
use dom::promise::Promise;
|
||||
use dom::screen::Screen;
|
||||
use dom::storage::Storage;
|
||||
use dom::testrunner::TestRunner;
|
||||
use euclid::{Point2D, Rect, Size2D};
|
||||
use fetch;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
|
@ -239,6 +240,8 @@ pub struct Window {
|
|||
|
||||
/// All the MediaQueryLists we need to update
|
||||
media_query_lists: WeakMediaQueryListVec,
|
||||
|
||||
test_runner: MutNullableHeap<JS<TestRunner>>,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
|
@ -881,6 +884,10 @@ impl WindowMethods for Window {
|
|||
fn Fetch(&self, input: RequestOrUSVString, init: &RequestInit) -> Rc<Promise> {
|
||||
fetch::Fetch(&self.upcast(), input, init)
|
||||
}
|
||||
|
||||
fn TestRunner(&self) -> Root<TestRunner> {
|
||||
self.test_runner.or_init(|| TestRunner::new(self.upcast()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
|
@ -1588,6 +1595,7 @@ impl Window {
|
|||
error_reporter: error_reporter,
|
||||
scroll_offsets: DOMRefCell::new(HashMap::new()),
|
||||
media_query_lists: WeakMediaQueryListVec::new(),
|
||||
test_runner: Default::default(),
|
||||
};
|
||||
|
||||
WindowBinding::Wrap(runtime.cx(), win)
|
||||
|
|
11
components/servo/Cargo.lock
generated
11
components/servo/Cargo.lock
generated
|
@ -199,6 +199,7 @@ dependencies = [
|
|||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)",
|
||||
"util 0.0.1",
|
||||
"uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -215,6 +216,14 @@ name = "blurdroid"
|
|||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "blurmock"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blurz"
|
||||
version = "0.2.1"
|
||||
|
@ -518,6 +527,7 @@ version = "0.0.1"
|
|||
source = "git+https://github.com/servo/devices#4a6ab4be0de229fafa6aa3657a5702646832ba08"
|
||||
dependencies = [
|
||||
"blurdroid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"blurmock 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"blurz 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -2905,6 +2915,7 @@ dependencies = [
|
|||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||
"checksum blurdroid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5fce4ea3366b583e9d49e1aa3a42252e53b42911bccd06f31c3e81c48ccfc79e"
|
||||
"checksum blurmock 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c3034c7372bc7951e0a916b7e952b0043cd4ccb5112cd30827f0e1708e05c2b1"
|
||||
"checksum blurz 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d49796c8d5a1b5f6b2b8686e46ed4ab842987c477f765b69f1d3e8df6072608"
|
||||
"checksum brotli 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bff2d5511b5ba5840f46cc3f9c0c3ab09db20e9b9a4db344ef7df3fb547a627a"
|
||||
"checksum browserhtml 0.1.17 (git+https://github.com/browserhtml/browserhtml?branch=crate)" = "<none>"
|
||||
|
|
11
ports/cef/Cargo.lock
generated
11
ports/cef/Cargo.lock
generated
|
@ -170,6 +170,7 @@ dependencies = [
|
|||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)",
|
||||
"util 0.0.1",
|
||||
"uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -186,6 +187,14 @@ name = "blurdroid"
|
|||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "blurmock"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blurz"
|
||||
version = "0.2.1"
|
||||
|
@ -473,6 +482,7 @@ version = "0.0.1"
|
|||
source = "git+https://github.com/servo/devices#4a6ab4be0de229fafa6aa3657a5702646832ba08"
|
||||
dependencies = [
|
||||
"blurdroid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"blurmock 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"blurz 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -2763,6 +2773,7 @@ dependencies = [
|
|||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||
"checksum blurdroid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5fce4ea3366b583e9d49e1aa3a42252e53b42911bccd06f31c3e81c48ccfc79e"
|
||||
"checksum blurmock 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c3034c7372bc7951e0a916b7e952b0043cd4ccb5112cd30827f0e1708e05c2b1"
|
||||
"checksum blurz 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d49796c8d5a1b5f6b2b8686e46ed4ab842987c477f765b69f1d3e8df6072608"
|
||||
"checksum brotli 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bff2d5511b5ba5840f46cc3f9c0c3ab09db20e9b9a4db344ef7df3fb547a627a"
|
||||
"checksum browserhtml 0.1.17 (git+https://github.com/browserhtml/browserhtml?branch=crate)" = "<none>"
|
||||
|
|
|
@ -40,6 +40,9 @@ f000ffc0-0451-4000-b000-000000000000
|
|||
# Block access to standardized unique identifiers, for privacy reasons.
|
||||
00002a25-0000-1000-8000-00805f9b34fb
|
||||
|
||||
# Blacklisted characteristic used to test readValue function.
|
||||
bad1c9a2-9a5b-4015-8b60-1579bbbf2135 exclude-reads
|
||||
|
||||
|
||||
## Descriptors
|
||||
|
||||
|
@ -50,4 +53,10 @@ f000ffc0-0451-4000-b000-000000000000
|
|||
|
||||
# org.bluetooth.descriptor.gatt.server_characteristic_configuration
|
||||
# Writing to this would let a web page interfere with the broadcasted services.
|
||||
00002903-0000-1000-8000-00805f9b34fb exclude-writes
|
||||
00002903-0000-1000-8000-00805f9b34fb exclude-writes
|
||||
|
||||
# Blacklisted descriptor used to test.
|
||||
07711111-6104-0970-7011-1107105110aaa
|
||||
|
||||
# Blacklisted descriptor used to test.
|
||||
aaaaaaaa-aaaa-1181-0510-810819516110 exclude-reads
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"dom.bluetooth.enabled": false,
|
||||
"dom.bluetooth.testing.enabled": false,
|
||||
"dom.forcetouch.enabled": true,
|
||||
"dom.mouseevent.which.enabled": false,
|
||||
"dom.mozbrowser.enabled": true,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"dom.bluetooth.enabled": false,
|
||||
"dom.bluetooth.testing.enabled": false,
|
||||
"dom.forcetouch.enabled": false,
|
||||
"dom.mouseevent.which.enabled": false,
|
||||
"dom.mozbrowser.enabled": false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue