diff options
author | Attila Dusnoki <dati91@gmail.com> | 2016-11-08 13:22:33 +0100 |
---|---|---|
committer | Attila Dusnoki <dati91@gmail.com> | 2016-11-08 13:27:56 +0100 |
commit | e7e7c74c9ee1a296683e01b97336ef9bdf7f009c (patch) | |
tree | ec5c711cc61bd94f3de4c1394b97ae1174eb5d95 /components/script/dom/bluetoothremotegattserver.rs | |
parent | 4a7ea7242935a9bea9ac82f82dd22b5ac8aad673 (diff) | |
download | servo-e7e7c74c9ee1a296683e01b97336ef9bdf7f009c.tar.gz servo-e7e7c74c9ee1a296683e01b97336ef9bdf7f009c.zip |
Webbluetooth Async behaviour
Diffstat (limited to 'components/script/dom/bluetoothremotegattserver.rs')
-rw-r--r-- | components/script/dom/bluetoothremotegattserver.rs | 194 |
1 files changed, 95 insertions, 99 deletions
diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs index 9ac1ca4c4f4..327062d063e 100644 --- a/components/script/dom/bluetoothremotegattserver.rs +++ b/components/script/dom/bluetoothremotegattserver.rs @@ -2,23 +2,24 @@ * 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 bluetooth_traits::{BluetoothRequest, BluetoothResponse}; use bluetooth_traits::blacklist::{Blacklist, uuid_is_blacklisted}; use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; -use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{self, Network, Security}; +use dom::bindings::error::ErrorResult; use dom::bindings::js::{JS, MutHeap, Root}; use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; -use dom::bluetooth::result_to_promise; +use dom::bluetooth::{AsyncBluetoothListener, response_async}; use dom::bluetoothdevice::BluetoothDevice; use dom::bluetoothremotegattservice::BluetoothRemoteGATTService; use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID}; use dom::globalscope::GlobalScope; use dom::promise::Promise; use ipc_channel::ipc::{self, IpcSender}; +use js::jsapi::JSContext; use std::cell::Cell; use std::rc::Rc; @@ -45,20 +46,42 @@ impl BluetoothRemoteGATTServer { BluetoothRemoteGATTServerBinding::Wrap) } - fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> { + fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> { self.global().as_window().bluetooth_thread() } +} + +impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-device + fn Device(&self) -> Root<BluetoothDevice> { + self.device.get() + } + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connected + fn Connected(&self) -> bool { + self.connected.get() + } + + #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect - fn connect(&self) -> Fallible<Root<BluetoothRemoteGATTServer>> { + fn Connect(&self) -> Rc<Promise> { + let p = Promise::new(&self.global()); + let sender = response_async(&p, self); + self.get_bluetooth_thread().send( + BluetoothRequest::GATTServerConnect(String::from(self.Device().Id()), sender)).unwrap(); + return p; + } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-disconnect + fn Disconnect(&self) -> ErrorResult { let (sender, receiver) = ipc::channel().unwrap(); self.get_bluetooth_thread().send( - BluetoothMethodMsg::GATTServerConnect(String::from(self.Device().Id()), sender)).unwrap(); + BluetoothRequest::GATTServerDisconnect(String::from(self.Device().Id()), sender)).unwrap(); let server = receiver.recv().unwrap(); match server { Ok(connected) => { self.connected.set(connected); - Ok(Root::from_ref(self)) + Ok(()) }, Err(error) => { Err(Error::from(error)) @@ -66,66 +89,90 @@ impl BluetoothRemoteGATTServer { } } + #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice - fn get_primary_service(&self, service: BluetoothServiceUUID) -> Fallible<Root<BluetoothRemoteGATTService>> { - let uuid = try!(BluetoothUUID::service(service)).to_string(); + fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Rc<Promise> { + let p = Promise::new(&self.global()); + let p_cx = p.global().get_cx(); + let uuid = match BluetoothUUID::service(service) { + Ok(uuid) => uuid.to_string(), + Err(e) => { + p.reject_error(p_cx, e); + return p; + } + }; if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) { - return Err(Security) + p.reject_error(p_cx, Security); + return p; } if !self.Device().Gatt().Connected() { - return Err(Network) + p.reject_error(p_cx, Network); + return p; } - let (sender, receiver) = ipc::channel().unwrap(); + let sender = response_async(&p, self); self.get_bluetooth_thread().send( - BluetoothMethodMsg::GetPrimaryService(String::from(self.Device().Id()), uuid, sender)).unwrap(); - let service = receiver.recv().unwrap(); - match service { - Ok(service) => { - let context = self.device.get().get_context(); - let mut service_map = context.get_service_map().borrow_mut(); - if let Some(existing_service) = service_map.get(&service.instance_id) { - return Ok(existing_service.get()); - } - let bt_service = BluetoothRemoteGATTService::new(&self.global(), - &self.device.get(), - DOMString::from(service.uuid), - service.is_primary, - service.instance_id.clone()); - service_map.insert(service.instance_id, MutHeap::new(&bt_service)); - Ok(bt_service) - }, - Err(error) => { - Err(Error::from(error)) - }, - } + BluetoothRequest::GetPrimaryService(String::from(self.Device().Id()), uuid, sender)).unwrap(); + return p; } + #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices - fn get_primary_services(&self, - service: Option<BluetoothServiceUUID>) - -> Fallible<Vec<Root<BluetoothRemoteGATTService>>> { + fn GetPrimaryServices(&self, service: Option<BluetoothServiceUUID>) -> Rc<Promise> { + let p = Promise::new(&self.global()); + let p_cx = p.global().get_cx(); let mut uuid: Option<String> = None; if let Some(s) = service { - uuid = Some(try!(BluetoothUUID::service(s)).to_string()); + 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 { if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) { - return Err(Security) + p.reject_error(p_cx, Security); + return p; } } }; if !self.Device().Gatt().Connected() { - return Err(Network) + p.reject_error(p_cx, Network); + return p; } - let mut services = vec!(); - let (sender, receiver) = ipc::channel().unwrap(); + let sender = response_async(&p, self); self.get_bluetooth_thread().send( - BluetoothMethodMsg::GetPrimaryServices(String::from(self.Device().Id()), uuid, sender)).unwrap(); - let services_vec = receiver.recv().unwrap(); - match services_vec { - Ok(service_vec) => { + 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>) { + match response { + BluetoothResponse::GATTServerConnect(connected) => { + self.connected.set(connected); + promise.resolve_native(promise_cx, self); + }, + BluetoothResponse::GetPrimaryService(service) => { + let context = self.device.get().get_context(); + let mut service_map = context.get_service_map().borrow_mut(); + if let Some(existing_service) = service_map.get(&service.instance_id) { + promise.resolve_native(promise_cx, &existing_service.get()); + } + let bt_service = BluetoothRemoteGATTService::new(&self.global(), + &self.device.get(), + DOMString::from(service.uuid), + service.is_primary, + service.instance_id.clone()); + service_map.insert(service.instance_id, MutHeap::new(&bt_service)); + promise.resolve_native(promise_cx, &bt_service); + }, + BluetoothResponse::GetPrimaryServices(services_vec) => { + let mut services = vec!(); let context = self.device.get().get_context(); let mut service_map = context.get_service_map().borrow_mut(); - for service in service_vec { + for service in services_vec { let bt_service = match service_map.get(&service.instance_id) { Some(existing_service) => existing_service.get(), None => { @@ -141,60 +188,9 @@ impl BluetoothRemoteGATTServer { } services.push(bt_service); } - Ok(services) - }, - Err(error) => { - Err(Error::from(error)) - }, - } - } -} - -impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-device - fn Device(&self) -> Root<BluetoothDevice> { - self.device.get() - } - - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connected - fn Connected(&self) -> bool { - self.connected.get() - } - - #[allow(unrooted_must_root)] - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect - fn Connect(&self) -> Rc<Promise> { - result_to_promise(&self.global(), self.connect()) - } - - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-disconnect - fn Disconnect(&self) -> ErrorResult { - let (sender, receiver) = ipc::channel().unwrap(); - self.get_bluetooth_thread().send( - BluetoothMethodMsg::GATTServerDisconnect(String::from(self.Device().Id()), sender)).unwrap(); - let server = receiver.recv().unwrap(); - match server { - Ok(connected) => { - self.connected.set(connected); - Ok(()) - }, - Err(error) => { - Err(Error::from(error)) + promise.resolve_native(promise_cx, &services); }, + _ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())), } } - - #[allow(unrooted_must_root)] - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice - fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Rc<Promise> { - result_to_promise(&self.global(), self.get_primary_service(service)) - } - - #[allow(unrooted_must_root)] - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices - fn GetPrimaryServices(&self, - service: Option<BluetoothServiceUUID>) - -> Rc<Promise> { - result_to_promise(&self.global(), self.get_primary_services(service)) - } } |