aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzakorgyula <gyula.zakor@gmail.com>2016-09-07 09:26:27 +0200
committerzakorgyula <gyula.zakor@gmail.com>2016-09-14 08:41:03 +0200
commitf4fda68409d3d6b85c6287e0559f88871f3a428c (patch)
tree22171575b9522fbb9242ee1acda7f3c8b35109a0
parent359548f60762b13716ca1d7a45077af77b8aa38f (diff)
downloadservo-f4fda68409d3d6b85c6287e0559f88871f3a428c.tar.gz
servo-f4fda68409d3d6b85c6287e0559f88871f3a428c.zip
Annotations for requestDevice, request_bluetooth_devices and matches_filter functions
-rw-r--r--components/net/bluetooth_thread.rs27
-rw-r--r--components/script/dom/bluetooth.rs62
2 files changed, 88 insertions, 1 deletions
diff --git a/components/net/bluetooth_thread.rs b/components/net/bluetooth_thread.rs
index e81ed2be8b6..efdeb02d7b2 100644
--- a/components/net/bluetooth_thread.rs
+++ b/components/net/bluetooth_thread.rs
@@ -84,17 +84,20 @@ impl BluetoothThreadFactory for IpcSender<BluetoothMethodMsg> {
}
}
+// https://webbluetoothcg.github.io/web-bluetooth/#matches-a-filter
fn matches_filter(device: &BluetoothDevice, filter: &BluetoothScanfilter) -> bool {
if filter.is_empty_or_invalid() {
return false;
}
+ // Step 1.
if !filter.get_name().is_empty() {
if device.get_name().ok() != Some(filter.get_name().to_string()) {
return false;
}
}
+ // Step 2.
if !filter.get_name_prefix().is_empty() {
if let Ok(device_name) = device.get_name() {
if !device_name.starts_with(filter.get_name_prefix()) {
@@ -105,6 +108,7 @@ fn matches_filter(device: &BluetoothDevice, filter: &BluetoothScanfilter) -> boo
}
}
+ // Step 3.
if !filter.get_services().is_empty() {
if let Ok(device_uuids) = device.get_uuids() {
for service in filter.get_services() {
@@ -115,6 +119,23 @@ fn matches_filter(device: &BluetoothDevice, filter: &BluetoothScanfilter) -> boo
}
}
+// Step 4.
+// TODO: Implement get_manufacturer_data in device crate.
+// if let Some(manufacturer_id) = filter.get_manufacturer_id() {
+// if !device.get_manufacturer_data().contains_key(manufacturer_id) {
+// return false;
+// }
+// }
+//
+// Step 5.
+// TODO: Implement get_device_data in device crate.
+// if !filter.get_service_data_uuid().is_empty() {
+// if !device.get_service_data().contains_key(filter.get_service_data_uuid()) {
+// return false;
+// }
+// }
+
+ // Step 6.
true
}
@@ -428,6 +449,7 @@ impl BluetoothManager {
// Methods
+ // https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
fn request_device(&mut self,
options: RequestDeviceoptions,
sender: IpcSender<BluetoothResult<BluetoothDeviceMsg>>) {
@@ -439,13 +461,18 @@ impl BluetoothManager {
let _ = session.stop_discovery();
}
+ // Step 6.
+ // Note: There is no requiredServiceUUIDS, we scan for all devices.
let mut matched_devices = self.get_and_cache_devices(&mut adapter);
+
+ // Step 7.
if !options.is_accepting_all_devices() {
matched_devices = matched_devices.into_iter()
.filter(|d| matches_filters(d, options.get_filters()))
.collect();
}
+ // Step 8.
if let Some(address) = self.select_device(matched_devices) {
let device_id = match self.address_to_id.get(&address) {
Some(id) => id.clone(),
diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs
index cac1cb7c7ee..2940a211bf3 100644
--- a/components/script/dom/bluetooth.rs
+++ b/components/script/dom/bluetooth.rs
@@ -66,10 +66,24 @@ impl Bluetooth {
filters: &Option<Vec<BluetoothRequestDeviceFilter>>,
optional_services: &Option<Vec<BluetoothServiceUUID>>)
-> Fallible<Root<BluetoothDevice>> {
+ // TODO: Step 1: Triggered by user activation.
+
+ // Step 2.
let option = try!(convert_request_device_options(self.global().r(), filters, optional_services));
+
+ // TODO: Step 3-5: Implement the permission API.
+
+ // Note: Steps 6-8 are implemented in
+ // components/net/bluetooth_thread.rs in request_device function.
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(BluetoothMethodMsg::RequestDevice(option, sender)).unwrap();
let device = receiver.recv().unwrap();
+
+ // TODO: Step 9-10: Implement the permission API.
+
+ // Step 11: This step is optional.
+
+ // Step 12-13.
match device {
Ok(device) => {
let ad_data = BluetoothAdvertisingData::new(self.global().r(),
@@ -89,16 +103,25 @@ impl Bluetooth {
}
}
+// https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
fn convert_request_device_options(global: GlobalRef,
filters: &Option<Vec<BluetoothRequestDeviceFilter>>,
optional_services: &Option<Vec<BluetoothServiceUUID>>)
-> Fallible<RequestDeviceoptions> {
+ // Step 2.2: There is no requiredServiceUUIDS, we scan for all devices.
let mut uuid_filters = vec!();
+
if let &Some(ref filters) = filters {
+ // Step 2.1.
if filters.is_empty() {
return Err(Type(FILTER_EMPTY_ERROR.to_owned()));
}
+
+ // Step 2.3: There is no requiredServiceUUIDS, we scan for all devices.
+
+ // Step 2.4.
for filter in filters {
+ // Step 2.4.8.
uuid_filters.push(try!(canonicalize_filter(&filter, global)));
}
}
@@ -106,8 +129,12 @@ fn convert_request_device_options(global: GlobalRef,
let mut optional_services_uuids = vec!();
if let &Some(ref opt_services) = optional_services {
for opt_service in opt_services {
+ // Step 2.5 - 2.6.
let uuid = try!(BluetoothUUID::GetService(global, opt_service.clone())).to_string();
+ // Step 2.7.
+ // Note: What we are doing here is adding the not blacklisted UUIDs to the result vector,
+ // insted of removing them from an already filled vector.
if !uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
optional_services_uuids.push(uuid);
}
@@ -118,7 +145,9 @@ fn convert_request_device_options(global: GlobalRef,
ServiceUUIDSequence::new(optional_services_uuids)))
}
+// https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter, global: GlobalRef) -> Fallible<BluetoothScanfilter> {
+ // Step 2.4.1.
if filter.services.is_none() &&
filter.name.is_none() &&
filter.namePrefix.is_none() &&
@@ -127,26 +156,41 @@ fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter, global: GlobalRef)
return Err(Type(FILTER_ERROR.to_owned()));
}
+ // Step 2.4.2: There is no empty canonicalizedFilter member,
+ // we create a BluetoothScanfilter instance at the end of the function.
+
+ // Step 2.4.3.
let services_vec = match filter.services {
Some(ref services) => {
+ // Step 2.4.3.1.
if services.is_empty() {
return Err(Type(SERVICE_ERROR.to_owned()));
}
+
let mut services_vec = vec!();
+
for service in services {
+ // Step 2.4.3.2 - 2.4.3.3.
let uuid = try!(BluetoothUUID::GetService(global, service.clone())).to_string();
+
+ // Step 2.4.3.4.
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
}
+
services_vec.push(uuid);
}
+ // Step 2.4.3.5.
services_vec
+ // Step 2.4.3.6: There is no requiredServiceUUIDS, we scan for all devices.
},
None => vec!(),
};
+ // Step 2.4.4.
let name = match filter.name {
Some(ref name) => {
+ // Step 2.4.4.1.
// Note: DOMString::len() gives back the size in bytes.
if name.len() > MAX_DEVICE_NAME_LENGTH {
return Err(Type(NAME_TOO_LONG_ERROR.to_owned()));
@@ -154,13 +198,17 @@ fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter, global: GlobalRef)
if name.len() > MAX_FILTER_NAME_LENGTH {
return Err(Type(FILTER_NAME_TOO_LONG_ERROR.to_owned()));
}
+
+ // Step 2.4.4.2.
name.to_string()
},
None => String::new(),
};
+ // Step 2.4.5.
let name_prefix = match filter.namePrefix {
Some(ref name_prefix) => {
+ // Step 2.4.5.1.
if name_prefix.is_empty() {
return Err(Type(NAME_PREFIX_ERROR.to_owned()));
}
@@ -170,19 +218,28 @@ fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter, global: GlobalRef)
if name_prefix.len() > MAX_FILTER_NAME_LENGTH {
return Err(Type(FILTER_NAME_TOO_LONG_ERROR.to_owned()));
}
+
+ // Step 2.4.5.2.
name_prefix.to_string()
},
None => String::new(),
};
+ // Step 2.4.6.
let manufacturer_id = filter.manufacturerId;
+ // Step 2.4.7.
let service_data_uuid = match filter.serviceDataUUID {
Some(ref service_data_uuid) => {
+ // Step 2.4.7.1 - 2.4.7.2.
let uuid = try!(BluetoothUUID::GetService(global, service_data_uuid.clone())).to_string();
+
+ // Step 2.4.7.3.
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
}
+
+ // Step 2.4.7.4.
uuid
},
None => String::new(),
@@ -210,15 +267,18 @@ impl From<BluetoothError> for Error {
impl BluetoothMethods for Bluetooth {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
fn RequestDevice(&self, option: &RequestDeviceOptions) -> Fallible<Root<BluetoothDevice>> {
+ // Step 1.
+ // TODO(#4282): Reject promise.
if (option.filters.is_some() && option.acceptAllDevices) ||
(option.filters.is_none() && !option.acceptAllDevices) {
return Err(Type(OPTIONS_ERROR.to_owned()));
}
-
+ // Step 2.
if !option.acceptAllDevices {
return self.request_bluetooth_devices(&option.filters, &option.optionalServices);
}
self.request_bluetooth_devices(&None, &option.optionalServices)
+ // TODO(#4282): Step 3-5: Reject and resolve promise.
}
}