diff options
Diffstat (limited to 'components/script/dom/bluetoothremotegattserver.rs')
-rw-r--r-- | components/script/dom/bluetoothremotegattserver.rs | 148 |
1 files changed, 38 insertions, 110 deletions
diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs index d9d57ae51f1..e81aae08abe 100644 --- a/components/script/dom/bluetoothremotegattserver.rs +++ b/components/script/dom/bluetoothremotegattserver.rs @@ -2,21 +2,20 @@ * 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::{BluetoothRequest, BluetoothResponse}; -use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted}; +use bluetooth_traits::{BluetoothRequest, BluetoothResponse, GATTType}; use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; -use dom::bindings::error::Error::{self, Network, Security}; +use dom::bindings::error::Error; use dom::bindings::error::ErrorResult; -use dom::bindings::js::{JS, MutHeap, Root}; +use dom::bindings::js::{MutJS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; -use dom::bluetooth::{AsyncBluetoothListener, response_async}; +use dom::bluetooth::{AsyncBluetoothListener, get_gatt_children, response_async}; use dom::bluetoothdevice::BluetoothDevice; use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID}; use dom::globalscope::GlobalScope; use dom::promise::Promise; -use ipc_channel::ipc::{self, IpcSender}; +use ipc_channel::ipc::IpcSender; use js::jsapi::JSContext; use std::cell::Cell; use std::rc::Rc; @@ -25,7 +24,7 @@ use std::rc::Rc; #[dom_struct] pub struct BluetoothRemoteGATTServer { reflector_: Reflector, - device: MutHeap<JS<BluetoothDevice>>, + device: MutJS<BluetoothDevice>, connected: Cell<bool>, } @@ -33,7 +32,7 @@ impl BluetoothRemoteGATTServer { pub fn new_inherited(device: &BluetoothDevice) -> BluetoothRemoteGATTServer { BluetoothRemoteGATTServer { reflector_: Reflector::new(), - device: MutHeap::new(device), + device: MutJS::new(device), connected: Cell::new(false), } } @@ -47,6 +46,10 @@ impl BluetoothRemoteGATTServer { fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> { self.global().as_window().bluetooth_thread() } + + pub fn set_connected(&self, connected: bool) { + self.connected.set(connected); + } } impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { @@ -67,17 +70,14 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { let p = Promise::new(&self.global()); let sender = response_async(&p, self); - // TODO: Step 2: Implement representedDevice internal slot for BluetoothDevice. - // TODO: Step 3: Check if the UA is currently using the Bluetooth system. // TODO: Step 4: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer. - // TODO: Step 5.1 - 5.2: Implement activeAlgorithms, representedDevice internal slots - // and the` garbage-collect the connection` algorithm. + // TODO: Step 5.1 - 5.2: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer. - // Note: Steps 5.1.1 and 5.1.3 are in components/bluetooth/lib.rs in the gatt_server_connect function. - // Steps 5.2.4 - 5.2.5 are in response function. + // Note: Steps 2, 5.1.1 and 5.1.3 are in components/bluetooth/lib.rs in the gatt_server_connect function. + // Steps 5.2.3 - 5.2.5 are in response function. self.get_bluetooth_thread().send( BluetoothRequest::GATTServerConnect(String::from(self.Device().Id()), sender)).unwrap(); // Step 5: return promise. @@ -90,135 +90,63 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { // Step 2. if !self.Connected() { - return Ok(()); + return Ok(()) } - let (sender, receiver) = ipc::channel().unwrap(); - self.get_bluetooth_thread().send( - BluetoothRequest::GATTServerDisconnect(String::from(self.Device().Id()), sender)).unwrap(); - let server = receiver.recv().unwrap(); - - // TODO: Step 3: Implement the `clean up the disconnected device` algorithm. - // TODO: Step 4: Implement representedDevice internal slot for BluetoothDevice. + // Step 3. + self.Device().clean_up_disconnected_device(); - // TODO: Step 5: Implement the `garbage-collect the connection` algorithm. - match server { - Ok(connected) => { - self.connected.set(connected); - Ok(()) - }, - Err(error) => { - Err(Error::from(error)) - }, - } + // Step 4 - 5: + self.Device().garbage_collect_the_connection() } #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Rc<Promise> { // TODO: Step 1: Implement the Permission API and the allowedServices BluetoothDevice internal slot. - // Subsequent steps are relative to https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - - // Step 1. - let uuid = match BluetoothUUID::service(service) { - Ok(uuid) => uuid.to_string(), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - - // Step 3 - 4. - if !self.Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedDevice internal slot for BluetoothDevice. - - // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_primary_service function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetPrimaryService(String::from(self.Device().Id()), uuid, sender)).unwrap(); - return p; + get_gatt_children(self, true, BluetoothUUID::service, Some(service), String::from(self.Device().Id()), + self.Device().Gatt().Connected(), GATTType::PrimaryService) } #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices fn GetPrimaryServices(&self, service: Option<BluetoothServiceUUID>) -> Rc<Promise> { // TODO: Step 1: Implement the Permission API and the allowedServices BluetoothDevice internal slot. - // Subsequent steps are relative to https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - - let mut uuid: Option<String> = None; - if let Some(s) = service { - // Step 1. - uuid = match BluetoothUUID::service(s) { - Ok(uuid) => Some(uuid.to_string()), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - if let Some(ref uuid) = uuid { - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - } - }; - - // Step 3 - 4. - if !self.Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedDevice internal slot for BluetoothDevice. + // Step 2. + get_gatt_children(self, false, BluetoothUUID::service, service, String::from(self.Device().Id()), + self.Connected(), GATTType::PrimaryService) - // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_primary_services function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetPrimaryServices(String::from(self.Device().Id()), uuid, sender)).unwrap(); - return p; } } impl AsyncBluetoothListener for BluetoothRemoteGATTServer { fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) { - let device = self.Device(); match response { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect BluetoothResponse::GATTServerConnect(connected) => { + // Step 5.2.3 + if self.Device().is_represented_device_null() { + if let Err(e) = self.Device().garbage_collect_the_connection() { + return promise.reject_error(promise_cx, Error::from(e)); + } + return promise.reject_error(promise_cx, Error::Network); + } + // Step 5.2.4. self.connected.set(connected); // Step 5.2.5. promise.resolve_native(promise_cx, self); }, - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren // Step 7. - BluetoothResponse::GetPrimaryService(service) => { - let bt_service = device.get_or_create_service(&service, &self); - promise.resolve_native(promise_cx, &bt_service); - }, - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - // Step 7. - BluetoothResponse::GetPrimaryServices(services_vec) => { + BluetoothResponse::GetPrimaryServices(services_vec, single) => { + let device = self.Device(); + if single { + promise.resolve_native(promise_cx, &device.get_or_create_service(&services_vec[0], &self)); + return; + } let mut services = vec!(); for service in services_vec { let bt_service = device.get_or_create_service(&service, &self); |