Auto merge of #14276 - szeged:notify, r=jdm

Add Start/Stop notifications

Add support for Start and Stop Notifications for WebBluetooth

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] There are tests for these changes

<!-- 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/14276)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-11-23 03:22:43 -08:00 committed by GitHub
commit c4b7cc863e
18 changed files with 364 additions and 4 deletions

View file

@ -7652,6 +7652,66 @@
"url": "/_mozilla/mozilla/bluetooth/requestDevice/two-filters.html"
}
],
"mozilla/bluetooth/startNotifications/blocklisted-characteristic.html": [
{
"path": "mozilla/bluetooth/startNotifications/blocklisted-characteristic.html",
"url": "/_mozilla/mozilla/bluetooth/startNotifications/blocklisted-characteristic.html"
}
],
"mozilla/bluetooth/startNotifications/characteristic-is-removed.html": [
{
"path": "mozilla/bluetooth/startNotifications/characteristic-is-removed.html",
"url": "/_mozilla/mozilla/bluetooth/startNotifications/characteristic-is-removed.html"
}
],
"mozilla/bluetooth/startNotifications/disconnect-called-before.html": [
{
"path": "mozilla/bluetooth/startNotifications/disconnect-called-before.html",
"url": "/_mozilla/mozilla/bluetooth/startNotifications/disconnect-called-before.html"
}
],
"mozilla/bluetooth/startNotifications/disconnect-called-during.html": [
{
"path": "mozilla/bluetooth/startNotifications/disconnect-called-during.html",
"url": "/_mozilla/mozilla/bluetooth/startNotifications/disconnect-called-during.html"
}
],
"mozilla/bluetooth/startNotifications/notify-failure.html": [
{
"path": "mozilla/bluetooth/startNotifications/notify-failure.html",
"url": "/_mozilla/mozilla/bluetooth/startNotifications/notify-failure.html"
}
],
"mozilla/bluetooth/startNotifications/notify-succeeds.html": [
{
"path": "mozilla/bluetooth/startNotifications/notify-succeeds.html",
"url": "/_mozilla/mozilla/bluetooth/startNotifications/notify-succeeds.html"
}
],
"mozilla/bluetooth/stopNotifications/characteristic-is-removed.html": [
{
"path": "mozilla/bluetooth/stopNotifications/characteristic-is-removed.html",
"url": "/_mozilla/mozilla/bluetooth/stopNotifications/characteristic-is-removed.html"
}
],
"mozilla/bluetooth/stopNotifications/disconnect-called-before.html": [
{
"path": "mozilla/bluetooth/stopNotifications/disconnect-called-before.html",
"url": "/_mozilla/mozilla/bluetooth/stopNotifications/disconnect-called-before.html"
}
],
"mozilla/bluetooth/stopNotifications/disconnect-called-during.html": [
{
"path": "mozilla/bluetooth/stopNotifications/disconnect-called-during.html",
"url": "/_mozilla/mozilla/bluetooth/stopNotifications/disconnect-called-during.html"
}
],
"mozilla/bluetooth/stopNotifications/notify-succeeds.html": [
{
"path": "mozilla/bluetooth/stopNotifications/notify-succeeds.html",
"url": "/_mozilla/mozilla/bluetooth/stopNotifications/notify-succeeds.html"
}
],
"mozilla/bluetooth/writeValue/characteristic/blocklisted-characteristic.html": [
{
"path": "mozilla/bluetooth/writeValue/characteristic/blocklisted-characteristic.html",

View file

@ -0,0 +1,4 @@
[disconnect-called-during.html]
type: testharness
[disconnect() called during startNotifications. Reject with NetworkError.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[disconnect-called-during.html]
type: testharness
[disconnect() called during stopNotifications. Reject with NetworkError.]
expected: FAIL

View file

@ -0,0 +1,17 @@
<!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(t => {
window.testRunner.setBluetoothMockDataSet(adapter_type.blocklist);
return window.navigator.bluetooth.requestDevice({
filters: [{services: [blocklist_test_service_uuid]}]
})
.then(device => device.gatt.connect())
.then(gattServer => gattServer.getPrimaryService(blocklist_test_service_uuid))
.then(service => service.getCharacteristic(blocklist_exclude_reads_characteristic_uuid))
.then(characteristic => promise_rejects(t, 'SecurityError', characteristic.startNotifications()));
}, 'Characteristic with exclude-reads rejects startNotifications.');
</script>

View file

@ -0,0 +1,21 @@
<!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(t => {
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(heart_rate.name))
.then(service => service.getCharacteristic(heart_rate_measurement.name))
.then(characteristic => {
window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
return promise_rejects(t, 'InvalidStateError', characteristic.startNotifications());
});
}, 'Characteristic gets removed. Reject with InvalidStateError.');
</script>

View file

@ -0,0 +1,23 @@
<!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(t => {
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 => {
return gattServer.getPrimaryService(heart_rate.name)
.then(service => service.getCharacteristic(heart_rate_measurement.name))
.then(characteristic => {
gattServer.disconnect();
return promise_rejects(t, 'NetworkError', characteristic.startNotifications());
});
});
}, 'disconnect() called before startNotifications. Reject with NetworkError.');
</script>

View file

@ -0,0 +1,24 @@
<!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(t => {
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 => {
return gattServer.getPrimaryService(heart_rate.name)
.then(service => service.getCharacteristic(heart_rate_measurement.name))
.then(characteristic => {
let promise = promise_rejects(t, 'NetworkError', characteristic.startNotifications());
gattServer.disconnect();
return promise;
});
});
}, 'disconnect() called during startNotifications. Reject with NetworkError.');
</script>

View file

@ -0,0 +1,20 @@
<!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(t => {
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 => {
return gattServer.getPrimaryService(generic_access.name)
.then(service => service.getCharacteristic(device_name.name))
.then(characteristic => promise_rejects(t, 'NotSupportedError', characteristic.startNotifications()));
});
}, 'startNotifications should throw NotSupportedError without Notify or Indicate flag.');
</script>

View file

@ -0,0 +1,21 @@
<!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(heart_rate.name))
.then(service => service.getCharacteristic(heart_rate_measurement.name))
.then(characteristic => {
return characteristic.startNotifications()
.then(result => assert_equals(result, characteristic));
});
}, 'startNotifications should return the caller object.');
</script>

View file

@ -0,0 +1,22 @@
<!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(t => {
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(heart_rate.name))
.then(service => service.getCharacteristic(heart_rate_measurement.name))
.then(characteristic => characteristic.startNotifications())
.then(characteristic => {
window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
return promise_rejects(t, 'InvalidStateError', characteristic.stopNotifications());
});
}, 'Characteristic gets removed. Reject with InvalidStateError.');
</script>

View file

@ -0,0 +1,24 @@
<!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(t => {
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 => {
return gattServer.getPrimaryService(heart_rate.name)
.then(service => service.getCharacteristic(heart_rate_measurement.name))
.then(characteristic => characteristic.startNotifications())
.then(characteristic => {
gattServer.disconnect();
return promise_rejects(t, 'NetworkError', characteristic.startNotifications());
});
});
}, 'disconnect() called before stopNotifications. Reject with NetworkError.');
</script>

View file

@ -0,0 +1,25 @@
<!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(t => {
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 => {
return gattServer.getPrimaryService(heart_rate.name)
.then(service => service.getCharacteristic(heart_rate_measurement.name))
.then(characteristic => characteristic.startNotifications())
.then(characteristic => {
let promise = promise_rejects(t, 'NetworkError', characteristic.startNotifications());
gattServer.disconnect();
return promise;
});
});
}, 'disconnect() called during stopNotifications. Reject with NetworkError.');
</script>

View file

@ -0,0 +1,22 @@
<!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(heart_rate.name))
.then(service => service.getCharacteristic(heart_rate_measurement.name))
.then(characteristic => characteristic.startNotifications())
.then(characteristic => {
return characteristic.stopNotifications()
.then(result => assert_equals(result, characteristic));
});
}, 'stopNotifications should return the caller object.');
</script>