aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bluetoothremotegattcharacteristic.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bluetoothremotegattcharacteristic.rs')
-rw-r--r--components/script/dom/bluetoothremotegattcharacteristic.rs283
1 files changed, 142 insertions, 141 deletions
diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs
index 1b2a16c1a4b..d5ff56853ce 100644
--- a/components/script/dom/bluetoothremotegattcharacteristic.rs
+++ b/components/script/dom/bluetoothremotegattcharacteristic.rs
@@ -2,7 +2,7 @@
* 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::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BluetoothCharacteristicPropertiesBinding::
@@ -13,19 +13,19 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding::
BluetoothRemoteGATTCharacteristicMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
-use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::error::Error::{self, InvalidModification, Network, NotSupported, Security};
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString};
-use dom::bluetooth::result_to_promise;
+use dom::bluetooth::{AsyncBluetoothListener, response_async};
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use dom::bluetoothuuid::{BluetoothDescriptorUUID, 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::rc::Rc;
// Maximum length of an attribute value.
@@ -73,196 +73,197 @@ impl BluetoothRemoteGATTCharacteristic {
BluetoothRemoteGATTCharacteristicBinding::Wrap)
}
- fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
+ fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> {
self.global().as_window().bluetooth_thread()
}
fn get_instance_id(&self) -> String {
self.instance_id.clone()
}
+}
+
+impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteristic {
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-properties
+ fn Properties(&self) -> Root<BluetoothCharacteristicProperties> {
+ self.properties.get()
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-service
+ fn Service(&self) -> Root<BluetoothRemoteGATTService> {
+ self.service.get()
+ }
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-uuid
+ fn Uuid(&self) -> DOMString {
+ self.uuid.clone()
+ }
+
+ #[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
- fn get_descriptor(&self, descriptor: BluetoothDescriptorUUID) -> Fallible<Root<BluetoothRemoteGATTDescriptor>> {
- let uuid = try!(BluetoothUUID::descriptor(descriptor)).to_string();
+ fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID) -> Rc<Promise> {
+ let p = Promise::new(&self.global());
+ let p_cx = p.global().get_cx();
+ let uuid = match BluetoothUUID::descriptor(descriptor) {
+ 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.Service().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::GetDescriptor(self.get_instance_id(), uuid, sender)).unwrap();
- let descriptor = receiver.recv().unwrap();
- match descriptor {
- Ok(descriptor) => {
- let context = self.service.get().get_device().get_context();
- let mut descriptor_map = context.get_descriptor_map().borrow_mut();
- if let Some(existing_descriptor) = descriptor_map.get(&descriptor.instance_id) {
- return Ok(existing_descriptor.get());
- }
- let bt_descriptor = BluetoothRemoteGATTDescriptor::new(&self.global(),
- self,
- DOMString::from(descriptor.uuid),
- descriptor.instance_id.clone());
- descriptor_map.insert(descriptor.instance_id, MutHeap::new(&bt_descriptor));
- Ok(bt_descriptor)
- },
- Err(error) => {
- Err(Error::from(error))
- },
- }
+ BluetoothRequest::GetDescriptor(self.get_instance_id(), uuid, sender)).unwrap();
+ return p;
}
+ #[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors
- fn get_descriptors(&self,
- descriptor: Option<BluetoothDescriptorUUID>)
- -> Fallible<Vec<Root<BluetoothRemoteGATTDescriptor>>> {
+ fn GetDescriptors(&self,
+ descriptor: Option<BluetoothDescriptorUUID>)
+ -> Rc<Promise> {
+ let p = Promise::new(&self.global());
+ let p_cx = p.global().get_cx();
let mut uuid: Option<String> = None;
if let Some(d) = descriptor {
- uuid = Some(try!(BluetoothUUID::descriptor(d)).to_string());
+ uuid = match BluetoothUUID::descriptor(d) {
+ 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.Service().Device().Gatt().Connected() {
- return Err(Network)
+ p.reject_error(p_cx, Network);
+ return p;
}
- let mut descriptors = vec!();
- let (sender, receiver) = ipc::channel().unwrap();
+ let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
- BluetoothMethodMsg::GetDescriptors(self.get_instance_id(), uuid, sender)).unwrap();
- let descriptors_vec = receiver.recv().unwrap();
- match descriptors_vec {
- Ok(descriptor_vec) => {
- let context = self.service.get().get_device().get_context();
- let mut descriptor_map = context.get_descriptor_map().borrow_mut();
- for descriptor in descriptor_vec {
- let bt_descriptor = match descriptor_map.get(&descriptor.instance_id) {
- Some(existing_descriptor) => existing_descriptor.get(),
- None => {
- BluetoothRemoteGATTDescriptor::new(&self.global(),
- self,
- DOMString::from(descriptor.uuid),
- descriptor.instance_id.clone())
- },
- };
- if !descriptor_map.contains_key(&descriptor.instance_id) {
- descriptor_map.insert(descriptor.instance_id, MutHeap::new(&bt_descriptor));
- }
- descriptors.push(bt_descriptor);
- }
- Ok(descriptors)
- },
- Err(error) => {
- Err(Error::from(error))
- },
- }
+ BluetoothRequest::GetDescriptors(self.get_instance_id(), uuid, sender)).unwrap();
+ return p;
}
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-value
+ fn GetValue(&self) -> Option<ByteString> {
+ self.value.borrow().clone()
+ }
+
+ #[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
- fn read_value(&self) -> Fallible<ByteString> {
+ fn ReadValue(&self) -> Rc<Promise> {
+ let p = Promise::new(&self.global());
+ let p_cx = p.global().get_cx();
if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Reads) {
- return Err(Security)
+ p.reject_error(p_cx, Security);
+ return p;
}
- let (sender, receiver) = ipc::channel().unwrap();
if !self.Service().Device().Gatt().Connected() {
- return Err(Network)
+ p.reject_error(p_cx, Network);
+ return p;
}
if !self.Properties().Read() {
- return Err(NotSupported)
+ p.reject_error(p_cx, NotSupported);
+ return p;
}
+ let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
- BluetoothMethodMsg::ReadValue(self.get_instance_id(), sender)).unwrap();
- let result = receiver.recv().unwrap();
- let value = match result {
- Ok(val) => {
- ByteString::new(val)
- },
- Err(error) => {
- return Err(Error::from(error))
- },
- };
- *self.value.borrow_mut() = Some(value.clone());
- Ok(value)
+ BluetoothRequest::ReadValue(self.get_instance_id(), sender)).unwrap();
+ return p;
}
+ #[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
- fn write_value(&self, value: Vec<u8>) -> ErrorResult {
+ fn WriteValue(&self, value: Vec<u8>) -> Rc<Promise> {
+ let p = Promise::new(&self.global());
+ let p_cx = p.global().get_cx();
if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Writes) {
- return Err(Security)
+ p.reject_error(p_cx, Security);
+ return p;
}
if value.len() > MAXIMUM_ATTRIBUTE_LENGTH {
- return Err(InvalidModification)
+ p.reject_error(p_cx, InvalidModification);
+ return p;
}
if !self.Service().Device().Gatt().Connected() {
- return Err(Network)
+ p.reject_error(p_cx, Network);
+ return p;
}
if !(self.Properties().Write() ||
self.Properties().WriteWithoutResponse() ||
self.Properties().AuthenticatedSignedWrites()) {
- return Err(NotSupported)
+ p.reject_error(p_cx, NotSupported);
+ return p;
}
- let (sender, receiver) = ipc::channel().unwrap();
+ let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
- BluetoothMethodMsg::WriteValue(self.get_instance_id(), value.clone(), sender)).unwrap();
- let result = receiver.recv().unwrap();
- match result {
- Ok(_) => Ok(*self.value.borrow_mut() = Some(ByteString::new(value))),
- Err(error) => {
- Err(Error::from(error))
- },
- }
+ BluetoothRequest::WriteValue(self.get_instance_id(), value, sender)).unwrap();
+ return p;
}
}
-impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteristic {
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-properties
- fn Properties(&self) -> Root<BluetoothCharacteristicProperties> {
- self.properties.get()
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-service
- fn Service(&self) -> Root<BluetoothRemoteGATTService> {
- self.service.get()
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-uuid
- fn Uuid(&self) -> DOMString {
- self.uuid.clone()
- }
-
- #[allow(unrooted_must_root)]
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
- fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID) -> Rc<Promise> {
- result_to_promise(&self.global(), self.get_descriptor(descriptor))
- }
-
- #[allow(unrooted_must_root)]
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors
- fn GetDescriptors(&self,
- descriptor: Option<BluetoothDescriptorUUID>)
- -> Rc<Promise> {
- result_to_promise(&self.global(), self.get_descriptors(descriptor))
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-value
- fn GetValue(&self) -> Option<ByteString> {
- self.value.borrow().clone()
- }
-
- #[allow(unrooted_must_root)]
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
- fn ReadValue(&self) -> Rc<Promise> {
- result_to_promise(&self.global(), self.read_value())
- }
-
- #[allow(unrooted_must_root)]
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
- fn WriteValue(&self, value: Vec<u8>) -> Rc<Promise> {
- result_to_promise(&self.global(), self.write_value(value))
+impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
+ fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) {
+ match response {
+ BluetoothResponse::GetDescriptor(descriptor) => {
+ let context = self.service.get().get_device().get_context();
+ let mut descriptor_map = context.get_descriptor_map().borrow_mut();
+ if let Some(existing_descriptor) = descriptor_map.get(&descriptor.instance_id) {
+ return promise.resolve_native(promise_cx, &existing_descriptor.get());
+ }
+ let bt_descriptor = BluetoothRemoteGATTDescriptor::new(&self.global(),
+ self,
+ DOMString::from(descriptor.uuid),
+ descriptor.instance_id.clone());
+ descriptor_map.insert(descriptor.instance_id, MutHeap::new(&bt_descriptor));
+ promise.resolve_native(promise_cx, &bt_descriptor);
+ },
+ BluetoothResponse::GetDescriptors(descriptors_vec) => {
+ let mut descriptors = vec!();
+ let context = self.service.get().get_device().get_context();
+ let mut descriptor_map = context.get_descriptor_map().borrow_mut();
+ for descriptor in descriptors_vec {
+ let bt_descriptor = match descriptor_map.get(&descriptor.instance_id) {
+ Some(existing_descriptor) => existing_descriptor.get(),
+ None => {
+ BluetoothRemoteGATTDescriptor::new(&self.global(),
+ self,
+ DOMString::from(descriptor.uuid),
+ descriptor.instance_id.clone())
+ },
+ };
+ if !descriptor_map.contains_key(&descriptor.instance_id) {
+ descriptor_map.insert(descriptor.instance_id, MutHeap::new(&bt_descriptor));
+ }
+ descriptors.push(bt_descriptor);
+ }
+ promise.resolve_native(promise_cx, &descriptors);
+ },
+ BluetoothResponse::ReadValue(result) => {
+ let value = ByteString::new(result);
+ *self.value.borrow_mut() = Some(value.clone());
+ promise.resolve_native(promise_cx, &value);
+ },
+ BluetoothResponse::WriteValue(result) => {
+ let value = ByteString::new(result);
+ *self.value.borrow_mut() = Some(value.clone());
+ promise.resolve_native(promise_cx, &value);
+ },
+ _ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
+ }
}
}