Skip to content

Commit

Permalink
Add event target for bluetooth
Browse files Browse the repository at this point in the history
  • Loading branch information
dati91 committed Nov 28, 2016
1 parent b18ec28 commit d9c7ffb
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 19 deletions.
1 change: 1 addition & 0 deletions components/atoms/static_atoms.txt
Expand Up @@ -77,3 +77,4 @@ toggle
statechange
controllerchange
fetch
characteristicvaluechanged
11 changes: 8 additions & 3 deletions components/script/dom/bluetooth.rs
Expand Up @@ -11,19 +11,21 @@ use core::clone::Clone;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BluetoothBinding::{self, BluetoothDataFilterInit, BluetoothLEScanFilterInit};
use dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothMethods, RequestDeviceOptions};
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::UnionTypes::StringOrUnsignedLong;
use dom::bindings::error::Error::{self, NotFound, Security, Type};
use dom::bindings::error::Fallible;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::refcounted::{Trusted, TrustedPromise};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
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;
use dom::promise::Promise;
use ipc_channel::ipc::{self, IpcSender};
Expand Down Expand Up @@ -84,7 +86,7 @@ impl<Listener: AsyncBluetoothListener + Reflectable> BluetoothResponseListener f
// https://webbluetoothcg.github.io/web-bluetooth/#bluetooth
#[dom_struct]
pub struct Bluetooth {
reflector_: Reflector,
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>>>>,
Expand All @@ -94,7 +96,7 @@ pub struct Bluetooth {
impl Bluetooth {
pub fn new_inherited() -> Bluetooth {
Bluetooth {
reflector_: Reflector::new(),
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()),
Expand Down Expand Up @@ -382,6 +384,9 @@ impl BluetoothMethods for Bluetooth {
// TODO(#4282): Step 3-5: Reject and resolve promise.
return p;
}

// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-onavailabilitychanged
event_handler!(availabilitychanged, GetOnavailabilitychanged, SetOnavailabilitychanged);
}

impl AsyncBluetoothListener for Bluetooth {
Expand Down
11 changes: 8 additions & 3 deletions components/script/dom/bluetoothdevice.rs
Expand Up @@ -4,18 +4,20 @@

use dom::bindings::codegen::Bindings::BluetoothDeviceBinding;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::js::{JS, Root, MutHeap, MutNullableHeap};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bluetooth::Bluetooth;
use dom::bluetoothadvertisingdata::BluetoothAdvertisingData;
use dom::bluetoothremotegattserver::BluetoothRemoteGATTServer;
use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;

// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice
#[dom_struct]
pub struct BluetoothDevice {
reflector_: Reflector,
eventtarget: EventTarget,
id: DOMString,
name: Option<DOMString>,
ad_data: MutHeap<JS<BluetoothAdvertisingData>>,
Expand All @@ -30,7 +32,7 @@ impl BluetoothDevice {
context: &Bluetooth)
-> BluetoothDevice {
BluetoothDevice {
reflector_: Reflector::new(),
eventtarget: EventTarget::new_inherited(),
id: id,
name: name,
ad_data: MutHeap::new(ad_data),
Expand Down Expand Up @@ -80,4 +82,7 @@ impl BluetoothDeviceMethods for BluetoothDevice {
BluetoothRemoteGATTServer::new(&self.global(), self)
})
}

// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdeviceeventhandlers-ongattserverdisconnected
event_handler!(gattserverdisconnected, GetOngattserverdisconnected, SetOngattserverdisconnected);
}
13 changes: 10 additions & 3 deletions components/script/dom/bluetoothremotegattcharacteristic.rs
Expand Up @@ -13,15 +13,18 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding::
BluetoothRemoteGATTCharacteristicMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::error::Error::{self, InvalidModification, Network, NotSupported, Security};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
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;
use dom::globalscope::GlobalScope;
use dom::promise::Promise;
use ipc_channel::ipc::IpcSender;
Expand All @@ -35,7 +38,7 @@ pub const MAXIMUM_ATTRIBUTE_LENGTH: usize = 512;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattcharacteristic
#[dom_struct]
pub struct BluetoothRemoteGATTCharacteristic {
reflector_: Reflector,
eventtarget: EventTarget,
service: MutHeap<JS<BluetoothRemoteGATTService>>,
uuid: DOMString,
properties: MutHeap<JS<BluetoothCharacteristicProperties>>,
Expand All @@ -50,7 +53,7 @@ impl BluetoothRemoteGATTCharacteristic {
instance_id: String)
-> BluetoothRemoteGATTCharacteristic {
BluetoothRemoteGATTCharacteristic {
reflector_: Reflector::new(),
eventtarget: EventTarget::new_inherited(),
service: MutHeap::new(service),
uuid: uuid,
properties: MutHeap::new(properties),
Expand Down Expand Up @@ -255,6 +258,9 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
sender)).unwrap();
return p;
}

// https://webbluetoothcg.github.io/web-bluetooth/#dom-characteristiceventhandlers-oncharacteristicvaluechanged
event_handler!(characteristicvaluechanged, GetOncharacteristicvaluechanged, SetOncharacteristicvaluechanged);
}

impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
Expand Down Expand Up @@ -297,6 +303,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
BluetoothResponse::ReadValue(result) => {
let value = ByteString::new(result);
*self.value.borrow_mut() = Some(value.clone());
self.upcast::<EventTarget>().fire_bubbling_event(atom!("characteristicvaluechanged"));
promise.resolve_native(promise_cx, &value);
},
BluetoothResponse::WriteValue(result) => {
Expand Down
17 changes: 14 additions & 3 deletions components/script/dom/bluetoothremotegattservice.rs
Expand Up @@ -8,15 +8,17 @@ use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMet
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::error::Error::{self, Network, Security};
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bluetooth::{AsyncBluetoothListener, response_async};
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
use dom::bluetoothuuid::{BluetoothCharacteristicUUID, BluetoothServiceUUID, BluetoothUUID};
use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
use dom::promise::Promise;
use ipc_channel::ipc::IpcSender;
Expand All @@ -26,7 +28,7 @@ use std::rc::Rc;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice
#[dom_struct]
pub struct BluetoothRemoteGATTService {
reflector_: Reflector,
eventtarget: EventTarget,
device: MutHeap<JS<BluetoothDevice>>,
uuid: DOMString,
is_primary: bool,
Expand All @@ -40,7 +42,7 @@ impl BluetoothRemoteGATTService {
instance_id: String)
-> BluetoothRemoteGATTService {
BluetoothRemoteGATTService {
reflector_: Reflector::new(),
eventtarget: EventTarget::new_inherited(),
device: MutHeap::new(device),
uuid: uuid,
is_primary: is_primary,
Expand Down Expand Up @@ -217,6 +219,15 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
sender)).unwrap();
return p;
}

// https://webbluetoothcg.github.io/web-bluetooth/#dom-serviceeventhandlers-onserviceadded
event_handler!(serviceadded, GetOnserviceadded, SetOnserviceadded);

// https://webbluetoothcg.github.io/web-bluetooth/#dom-serviceeventhandlers-onservicechanged
event_handler!(servicechanged, GetOnservicechanged, SetOnservicechanged);

// https://webbluetoothcg.github.io/web-bluetooth/#dom-serviceeventhandlers-onserviceremoved
event_handler!(serviceremoved, GetOnserviceremoved, SetOnserviceremoved);
}

impl AsyncBluetoothListener for BluetoothRemoteGATTService {
Expand Down
3 changes: 2 additions & 1 deletion components/script/dom/webidls/Bluetooth.webidl
Expand Up @@ -28,9 +28,10 @@ dictionary RequestDeviceOptions {
};

[Pref="dom.bluetooth.enabled"]
interface Bluetooth {
interface Bluetooth : EventTarget {
// [SecureContext]
// readonly attribute BluetoothDevice? referringDevice;
attribute EventHandler onavailabilitychanged;
// [SecureContext]
// Promise<boolean> getAvailability();
// [SecureContext]
Expand Down
9 changes: 7 additions & 2 deletions components/script/dom/webidls/BluetoothDevice.webidl
Expand Up @@ -5,7 +5,7 @@
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice

[Pref="dom.bluetooth.enabled"]
interface BluetoothDevice {
interface BluetoothDevice : EventTarget {
readonly attribute DOMString id;
readonly attribute DOMString? name;
// TODO: remove this after BluetoothAdvertisingEvent implemented.
Expand All @@ -17,7 +17,12 @@ interface BluetoothDevice {
// readonly attribute boolean watchingAdvertisements;
};

[NoInterfaceObject]
interface BluetoothDeviceEventHandlers {
attribute EventHandler ongattserverdisconnected;
};

// BluetoothDevice implements EventTarget;
// BluetoothDevice implements BluetoothDeviceEventHandlers;
BluetoothDevice implements BluetoothDeviceEventHandlers;
// BluetoothDevice implements CharacteristicEventHandlers;
// BluetoothDevice implements ServiceEventHandlers;
Expand Up @@ -5,7 +5,7 @@
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattcharacteristic

[Pref="dom.bluetooth.enabled"]
interface BluetoothRemoteGATTCharacteristic {
interface BluetoothRemoteGATTCharacteristic : EventTarget {
readonly attribute BluetoothRemoteGATTService service;
readonly attribute DOMString uuid;
readonly attribute BluetoothCharacteristicProperties properties;
Expand All @@ -21,5 +21,10 @@ interface BluetoothRemoteGATTCharacteristic {
Promise<BluetoothRemoteGATTCharacteristic> stopNotifications();
};

//BluetootRemoteGATTCharacteristic implements EventTarget;
//BluetootRemoteGATTCharacteristic implements CharacteristicEventHandlers;
[NoInterfaceObject]
interface CharacteristicEventHandlers {
attribute EventHandler oncharacteristicvaluechanged;
};

// BluetoothRemoteGATTCharacteristic implements EventTarget;
BluetoothRemoteGATTCharacteristic implements CharacteristicEventHandlers;
13 changes: 12 additions & 1 deletion components/script/dom/webidls/BluetoothRemoteGATTService.webidl
Expand Up @@ -5,7 +5,7 @@
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice

[Pref="dom.bluetooth.enabled"]
interface BluetoothRemoteGATTService {
interface BluetoothRemoteGATTService : EventTarget {
readonly attribute BluetoothDevice device;
readonly attribute DOMString uuid;
readonly attribute boolean isPrimary;
Expand All @@ -15,3 +15,14 @@ interface BluetoothRemoteGATTService {
Promise<BluetoothRemoteGATTService> getIncludedService(BluetoothServiceUUID service);
Promise<sequence<BluetoothRemoteGATTService>> getIncludedServices(optional BluetoothServiceUUID service);
};

[NoInterfaceObject]
interface ServiceEventHandlers {
attribute EventHandler onserviceadded;
attribute EventHandler onservicechanged;
attribute EventHandler onserviceremoved;
};

// BluetoothRemoteGATTService implements EventTarget;
// BluetoothRemoteGATTService implements CharacteristicEventHandlers;
BluetoothRemoteGATTService implements ServiceEventHandlers;
6 changes: 6 additions & 0 deletions tests/wpt/mozilla/meta/MANIFEST.json
Expand Up @@ -7268,6 +7268,12 @@
"url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html"
}
],
"mozilla/bluetooth/readValue/characteristic/event-is-fired.html": [
{
"path": "mozilla/bluetooth/readValue/characteristic/event-is-fired.html",
"url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/event-is-fired.html"
}
],
"mozilla/bluetooth/readValue/characteristic/read-succeeds.html": [
{
"path": "mozilla/bluetooth/readValue/characteristic/read-succeeds.html",
Expand Down
@@ -0,0 +1,35 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script>
<script>
'use strict';
promise_test(() => {
window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
return window.navigator.bluetooth.requestDevice({
filters: [{services: [heart_rate.name]}],
optionalServices: [generic_access.name]
})
.then(device => device.gatt.connect())
.then(gattServer => gattServer.getPrimaryService(generic_access.name))
.then(service => service.getCharacteristic(device_name.name))
.then(characteristic => {
let event = 'characteristicvaluechanged';
let event_promise = new Promise((resolve, reject) => {
let event_listener = (e) => {
characteristic.removeEventListener(event, event_listener);
resolve(e.target.value);
};
characteristic.addEventListener(event, event_listener);
});
return characteristic.readValue()
.then(result => {
return Promise.all([result, event_promise]);
});
}).then(results => {
let read_value = results[0];
let event_value = results[1];
assert_array_equals(event_value, read_value);
});
}, 'Reading a characteristic should fire an event.');
</script>

0 comments on commit d9c7ffb

Please sign in to comment.