Skip to content

Commit

Permalink
Auto merge of #14441 - szeged:attribute-instance-map, r=jdm
Browse files Browse the repository at this point in the history
Move the AttributeInstanceMaps from bluetooth to bluetoothDevice.

<!-- Please describe your changes on the following line: -->
The previous implementation differed from the spec, because there was three maps instead of one. With this, they will be merged into one.
Also this map has been moved from bluetooth to bluetoothDevice, because its make more sense to store it there. There is an issue about it [here](WebBluetoothCG/web-bluetooth#330).

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors

<!-- Either: -->
- [X] There are tests for these changes

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14441)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Dec 6, 2016
2 parents 73b6e70 + 92df124 commit 2e1c40e
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 132 deletions.
22 changes: 0 additions & 22 deletions components/script/dom/bluetooth.rs
Expand Up @@ -21,9 +21,6 @@ use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bluetoothadvertisingdata::BluetoothAdvertisingData;
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID};
use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
Expand Down Expand Up @@ -90,19 +87,13 @@ impl<Listener: AsyncBluetoothListener + Reflectable> BluetoothResponseListener f
pub struct Bluetooth {
eventtarget: EventTarget,
device_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothDevice>>>>,
service_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTService>>>>,
characteristic_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTCharacteristic>>>>,
descriptor_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTDescriptor>>>>,
}

impl Bluetooth {
pub fn new_inherited() -> Bluetooth {
Bluetooth {
eventtarget: EventTarget::new_inherited(),
device_instance_map: DOMRefCell::new(HashMap::new()),
service_instance_map: DOMRefCell::new(HashMap::new()),
characteristic_instance_map: DOMRefCell::new(HashMap::new()),
descriptor_instance_map: DOMRefCell::new(HashMap::new()),
}
}

Expand All @@ -112,19 +103,6 @@ impl Bluetooth {
BluetoothBinding::Wrap)
}

pub fn get_service_map(&self) -> &DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTService>>>> {
&self.service_instance_map
}

pub fn get_characteristic_map(&self)
-> &DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTCharacteristic>>>> {
&self.characteristic_instance_map
}

pub fn get_descriptor_map(&self) -> &DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTDescriptor>>>> {
&self.descriptor_instance_map
}

fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> {
self.global().as_window().bluetooth_thread()
}
Expand Down
79 changes: 77 additions & 2 deletions components/script/dom/bluetoothdevice.rs
Expand Up @@ -2,17 +2,26 @@
* 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::{BluetoothCharacteristicMsg, BluetoothDescriptorMsg, BluetoothServiceMsg};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::js::{JS, Root, MutHeap, MutNullableHeap};
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bluetooth::Bluetooth;
use dom::bluetoothadvertisingdata::BluetoothAdvertisingData;
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor;
use dom::bluetoothremotegattserver::BluetoothRemoteGATTServer;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
use std::collections::HashMap;


// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice
#[dom_struct]
Expand All @@ -23,6 +32,9 @@ pub struct BluetoothDevice {
ad_data: MutHeap<JS<BluetoothAdvertisingData>>,
gatt: MutNullableHeap<JS<BluetoothRemoteGATTServer>>,
context: MutHeap<JS<Bluetooth>>,
attribute_instance_map: (DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTService>>>>,
DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTCharacteristic>>>>,
DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTDescriptor>>>>),
}

impl BluetoothDevice {
Expand All @@ -38,6 +50,9 @@ impl BluetoothDevice {
ad_data: MutHeap::new(ad_data),
gatt: Default::default(),
context: MutHeap::new(context),
attribute_instance_map: (DOMRefCell::new(HashMap::new()),
DOMRefCell::new(HashMap::new()),
DOMRefCell::new(HashMap::new())),
}
}

Expand All @@ -55,8 +70,68 @@ impl BluetoothDevice {
BluetoothDeviceBinding::Wrap)
}

pub fn get_context(&self) -> Root<Bluetooth> {
self.context.get()
pub fn get_or_create_service(&self,
service: &BluetoothServiceMsg,
server: &BluetoothRemoteGATTServer)
-> Root<BluetoothRemoteGATTService> {
let (ref service_map_ref, _, _) = self.attribute_instance_map;
let mut service_map = service_map_ref.borrow_mut();
if let Some(existing_service) = service_map.get(&service.instance_id) {
return existing_service.get();
}
let bt_service = BluetoothRemoteGATTService::new(&server.global(),
&server.Device(),
DOMString::from(service.uuid.clone()),
service.is_primary,
service.instance_id.clone());
service_map.insert(service.instance_id.clone(), MutHeap::new(&bt_service));
return bt_service;
}

pub fn get_or_create_characteristic(&self,
characteristic: &BluetoothCharacteristicMsg,
service: &BluetoothRemoteGATTService)
-> Root<BluetoothRemoteGATTCharacteristic> {
let (_, ref characteristic_map_ref, _) = self.attribute_instance_map;
let mut characteristic_map = characteristic_map_ref.borrow_mut();
if let Some(existing_characteristic) = characteristic_map.get(&characteristic.instance_id) {
return existing_characteristic.get();
}
let properties =
BluetoothCharacteristicProperties::new(&service.global(),
characteristic.broadcast,
characteristic.read,
characteristic.write_without_response,
characteristic.write,
characteristic.notify,
characteristic.indicate,
characteristic.authenticated_signed_writes,
characteristic.reliable_write,
characteristic.writable_auxiliaries);
let bt_characteristic = BluetoothRemoteGATTCharacteristic::new(&service.global(),
service,
DOMString::from(characteristic.uuid.clone()),
&properties,
characteristic.instance_id.clone());
characteristic_map.insert(characteristic.instance_id.clone(), MutHeap::new(&bt_characteristic));
return bt_characteristic;
}

pub fn get_or_create_descriptor(&self,
descriptor: &BluetoothDescriptorMsg,
characteristic: &BluetoothRemoteGATTCharacteristic)
-> Root<BluetoothRemoteGATTDescriptor> {
let (_, _, ref descriptor_map_ref) = self.attribute_instance_map;
let mut descriptor_map = descriptor_map_ref.borrow_mut();
if let Some(existing_descriptor) = descriptor_map.get(&descriptor.instance_id) {
return existing_descriptor.get();
}
let bt_descriptor = BluetoothRemoteGATTDescriptor::new(&characteristic.global(),
characteristic,
DOMString::from(descriptor.uuid.clone()),
descriptor.instance_id.clone());
descriptor_map.insert(descriptor.instance_id.clone(), MutHeap::new(&bt_descriptor));
return bt_descriptor;
}
}

Expand Down
28 changes: 3 additions & 25 deletions components/script/dom/bluetoothremotegattcharacteristic.rs
Expand Up @@ -21,7 +21,6 @@ use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString};
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::eventtarget::EventTarget;
Expand Down Expand Up @@ -330,43 +329,22 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris

impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) {
let device = self.Service().Device();
match response {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
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));
let bt_descriptor = device.get_or_create_descriptor(&descriptor, &self);
promise.resolve_native(promise_cx, &bt_descriptor);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
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));
}
let bt_descriptor = device.get_or_create_descriptor(&descriptor, &self);
descriptors.push(bt_descriptor);
}
promise.resolve_native(promise_cx, &descriptors);
Expand Down
31 changes: 3 additions & 28 deletions components/script/dom/bluetoothremotegattserver.rs
Expand Up @@ -11,10 +11,8 @@ 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::{AsyncBluetoothListener, response_async};
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID};
use dom::globalscope::GlobalScope;
use dom::promise::Promise;
Expand Down Expand Up @@ -200,6 +198,7 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {

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) => {
Expand All @@ -213,40 +212,16 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer {
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
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));
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) => {
let mut services = vec!();
let context = self.device.get().get_context();
let mut service_map = context.get_service_map().borrow_mut();
for service in services_vec {
let bt_service = match service_map.get(&service.instance_id) {
Some(existing_service) => existing_service.get(),
None => {
BluetoothRemoteGATTService::new(&self.global(),
&self.device.get(),
DOMString::from(service.uuid),
service.is_primary,
service.instance_id.clone())
},
};
if !service_map.contains_key(&service.instance_id) {
service_map.insert(service.instance_id, MutHeap::new(&bt_service));
}
let bt_service = device.get_or_create_service(&service, &self);
services.push(bt_service);
}
promise.resolve_native(promise_cx, &services);
Expand Down

0 comments on commit 2e1c40e

Please sign in to comment.