aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bluetooth.rs
diff options
context:
space:
mode:
authorzakorgyula <gyula.zakor@gmail.com>2016-09-07 08:08:51 +0200
committerzakorgyula <gyula.zakor@gmail.com>2016-09-14 08:41:01 +0200
commit057b93f2e69a8bc89bf9f802e4c2ab4546a7bb98 (patch)
tree3d40d7754e8e105c3ad5bf498b140e8b37b13bd4 /components/script/dom/bluetooth.rs
parentbb53da69578887befae195b18255967cc7f3fc59 (diff)
downloadservo-057b93f2e69a8bc89bf9f802e4c2ab4546a7bb98.tar.gz
servo-057b93f2e69a8bc89bf9f802e4c2ab4546a7bb98.zip
requestDevice refactor
Diffstat (limited to 'components/script/dom/bluetooth.rs')
-rw-r--r--components/script/dom/bluetooth.rs173
1 files changed, 95 insertions, 78 deletions
diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs
index 6540f6c971f..b6c04a1e867 100644
--- a/components/script/dom/bluetooth.rs
+++ b/components/script/dom/bluetooth.rs
@@ -15,13 +15,13 @@ use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bluetoothadvertisingdata::BluetoothAdvertisingData;
use dom::bluetoothdevice::BluetoothDevice;
-use dom::bluetoothuuid::BluetoothUUID;
+use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID};
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence};
use net_traits::bluetooth_scanfilter::{RequestDeviceoptions, ServiceUUIDSequence};
use net_traits::bluetooth_thread::{BluetoothError, BluetoothMethodMsg};
-const FILTER_EMPTY_ERROR: &'static str = "'filters' member must be non - empty to find any devices.";
+const FILTER_EMPTY_ERROR: &'static str = "'filters' member must be nonempty to find any devices.";
const FILTER_ERROR: &'static str = "A filter must restrict the devices in some way.";
const FILTER_NAME_TOO_LONG_ERROR: &'static str = "A 'name' or 'namePrefix' can't be longer then 29 bytes.";
// 248 is the maximum number of UTF-8 code units in a Bluetooth Device Name.
@@ -31,7 +31,7 @@ const MAX_DEVICE_NAME_LENGTH: usize = 248;
// The length and identifier of the length field take 2 bytes.
// That leaves 29 bytes for the name.
const MAX_FILTER_NAME_LENGTH: usize = 29;
-const NAME_PREFIX_ERROR: &'static str = "'namePrefix', if present, must be non - empty.";
+const NAME_PREFIX_ERROR: &'static str = "'namePrefix', if present, must be nonempty.";
const NAME_TOO_LONG_ERROR: &'static str = "A device name can't be longer than 248 bytes.";
const SERVICE_ERROR: &'static str = "'services', if present, must contain at least one service.";
@@ -59,80 +59,115 @@ impl Bluetooth {
let global_ref = global_root.r();
global_ref.as_window().bluetooth_thread()
}
-}
-
-fn canonicalize_filter(filter: &BluetoothScanFilter, global: GlobalRef) -> Fallible<BluetoothScanfilter> {
- if filter.services.is_none() && filter.name.is_none() && filter.namePrefix.is_none() {
- return Err(Type(FILTER_ERROR.to_owned()));
- }
-
- let mut services_vec = vec!();
- if let Some(ref services) = filter.services {
- if services.is_empty() {
- return Err(Type(SERVICE_ERROR.to_owned()));
- }
- for service in services {
- let uuid = try!(BluetoothUUID::GetService(global, service.clone())).to_string();
- if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
- return Err(Security)
- }
- services_vec.push(uuid);
- }
- }
- let mut name = String::new();
- if let Some(ref filter_name) = filter.name {
- //NOTE: DOMString::len() gives back the size in bytes
- if filter_name.len() > MAX_DEVICE_NAME_LENGTH {
- return Err(Type(NAME_TOO_LONG_ERROR.to_owned()));
- }
- if filter_name.len() > MAX_FILTER_NAME_LENGTH {
- return Err(Type(FILTER_NAME_TOO_LONG_ERROR.to_owned()));
- }
- name = filter_name.to_string();
- }
-
- let mut name_prefix = String::new();
- if let Some(ref filter_name_prefix) = filter.namePrefix {
- if filter_name_prefix.is_empty() {
- return Err(Type(NAME_PREFIX_ERROR.to_owned()));
- }
- if filter_name_prefix.len() > MAX_DEVICE_NAME_LENGTH {
- return Err(Type(NAME_TOO_LONG_ERROR.to_owned()));
- }
- if filter_name_prefix.len() > MAX_FILTER_NAME_LENGTH {
- return Err(Type(FILTER_NAME_TOO_LONG_ERROR.to_owned()));
+ // https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
+ fn request_bluetooth_devices(&self,
+ filters: &[BluetoothScanFilter],
+ optional_services: &Option<Vec<BluetoothServiceUUID>>)
+ -> Fallible<Root<BluetoothDevice>> {
+ let option = try!(convert_request_device_options(self.global().r(), filters, optional_services));
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.get_bluetooth_thread().send(BluetoothMethodMsg::RequestDevice(option, sender)).unwrap();
+ let device = receiver.recv().unwrap();
+ match device {
+ Ok(device) => {
+ let ad_data = BluetoothAdvertisingData::new(self.global().r(),
+ device.appearance,
+ device.tx_power,
+ device.rssi);
+ Ok(BluetoothDevice::new(self.global().r(),
+ DOMString::from(device.id),
+ device.name.map(DOMString::from),
+ &ad_data))
+ },
+ Err(error) => {
+ Err(Error::from(error))
+ },
}
- name_prefix = filter_name_prefix.to_string();
}
-
- Ok(BluetoothScanfilter::new(name, name_prefix, services_vec))
}
-fn convert_request_device_options(options: &RequestDeviceOptions,
- global: GlobalRef)
+fn convert_request_device_options(global: GlobalRef,
+ filters: &[BluetoothScanFilter],
+ optional_services: &Option<Vec<BluetoothServiceUUID>>)
-> Fallible<RequestDeviceoptions> {
- if options.filters.is_empty() {
+ if filters.is_empty() {
return Err(Type(FILTER_EMPTY_ERROR.to_owned()));
}
- let mut filters = vec!();
- for filter in &options.filters {
- filters.push(try!(canonicalize_filter(&filter, global)));
+ let mut filters_vec = vec!();
+ for filter in filters {
+ filters_vec.push(try!(canonicalize_filter(&filter, global)));
}
- let mut optional_services = vec!();
- if let Some(ref opt_services) = options.optionalServices {
+ let mut optional_services_vec = vec!();
+ if let &Some(ref opt_services) = optional_services {
for opt_service in opt_services {
let uuid = try!(BluetoothUUID::GetService(global, opt_service.clone())).to_string();
if !uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
- optional_services.push(uuid);
+ optional_services_vec.push(uuid);
}
}
}
- Ok(RequestDeviceoptions::new(BluetoothScanfilterSequence::new(filters),
- ServiceUUIDSequence::new(optional_services)))
+ Ok(RequestDeviceoptions::new(BluetoothScanfilterSequence::new(filters_vec),
+ ServiceUUIDSequence::new(optional_services_vec)))
+}
+
+fn canonicalize_filter(filter: &BluetoothScanFilter, global: GlobalRef) -> Fallible<BluetoothScanfilter> {
+ if filter.services.is_none() && filter.name.is_none() && filter.namePrefix.is_none() {
+ return Err(Type(FILTER_ERROR.to_owned()));
+ }
+
+ let services_vec = match filter.services {
+ Some(ref services) => {
+ if services.is_empty() {
+ return Err(Type(SERVICE_ERROR.to_owned()));
+ }
+ let mut services_vec = vec!();
+ for service in services {
+ let uuid = try!(BluetoothUUID::GetService(global, service.clone())).to_string();
+ if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
+ return Err(Security)
+ }
+ services_vec.push(uuid);
+ }
+ services_vec
+ },
+ None => vec!(),
+ };
+
+ let name = match filter.name {
+ Some(ref name) => {
+ // 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()));
+ }
+ if name.len() > MAX_FILTER_NAME_LENGTH {
+ return Err(Type(FILTER_NAME_TOO_LONG_ERROR.to_owned()));
+ }
+ name.to_string()
+ },
+ None => String::new(),
+ };
+
+ let name_prefix = match filter.namePrefix {
+ Some(ref name_prefix) => {
+ if name_prefix.is_empty() {
+ return Err(Type(NAME_PREFIX_ERROR.to_owned()));
+ }
+ if name_prefix.len() > MAX_DEVICE_NAME_LENGTH {
+ return Err(Type(NAME_TOO_LONG_ERROR.to_owned()));
+ }
+ if name_prefix.len() > MAX_FILTER_NAME_LENGTH {
+ return Err(Type(FILTER_NAME_TOO_LONG_ERROR.to_owned()));
+ }
+ name_prefix.to_string()
+ },
+ None => String::new(),
+ };
+
+ Ok(BluetoothScanfilter::new(name, name_prefix, services_vec))
}
impl From<BluetoothError> for Error {
@@ -150,24 +185,6 @@ 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>> {
- let (sender, receiver) = ipc::channel().unwrap();
- let option = try!(convert_request_device_options(option, self.global().r()));
- self.get_bluetooth_thread().send(BluetoothMethodMsg::RequestDevice(option, sender)).unwrap();
- let device = receiver.recv().unwrap();
- match device {
- Ok(device) => {
- let ad_data = BluetoothAdvertisingData::new(self.global().r(),
- device.appearance,
- device.tx_power,
- device.rssi);
- Ok(BluetoothDevice::new(self.global().r(),
- DOMString::from(device.id),
- device.name.map(DOMString::from),
- &ad_data))
- },
- Err(error) => {
- Err(Error::from(error))
- },
- }
+ self.request_bluetooth_devices(&option.filters, &option.optionalServices)
}
}