Skip to content

Commit eb2484f

Browse files
author
bors-servo
authored
Auto merge of #13918 - szeged:wpt-error-fixes, r=jdm
WebBluetooth fixes for the wpt tests <!-- Please describe your changes on the following line: --> Note: depends on #13612 WebBluetooth fixes for the failing wpt tests, excluding the `disconnect-during` tests cases, due to the lack of the event handling in the current implementation. --- <!-- 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 - [x] There are tests for these changes OR <!-- 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/13918) <!-- Reviewable:end -->
2 parents 94d0c48 + 91a0c4d commit eb2484f

File tree

230 files changed

+455
-492
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

230 files changed

+455
-492
lines changed

components/bluetooth/lib.rs

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use bluetooth_traits::{BluetoothCharacteristicMsg, BluetoothCharacteristicsMsg};
1919
use bluetooth_traits::{BluetoothDescriptorMsg, BluetoothDescriptorsMsg};
2020
use bluetooth_traits::{BluetoothDeviceMsg, BluetoothError, BluetoothMethodMsg};
2121
use bluetooth_traits::{BluetoothResult, BluetoothServiceMsg, BluetoothServicesMsg};
22+
use bluetooth_traits::blacklist::{uuid_is_blacklisted, Blacklist};
2223
use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence, RequestDeviceoptions};
2324
use device::bluetooth::{BluetoothAdapter, BluetoothDevice, BluetoothGATTCharacteristic};
2425
use device::bluetooth::{BluetoothGATTDescriptor, BluetoothGATTService};
@@ -31,10 +32,6 @@ use std::thread;
3132
use std::time::Duration;
3233
use util::thread::spawn_named;
3334

34-
const ADAPTER_ERROR: &'static str = "No adapter found";
35-
36-
const ADAPTER_NOT_POWERED_ERROR: &'static str = "Bluetooth adapter not powered";
37-
3835
// A transaction not completed within 30 seconds shall time out. Such a transaction shall be considered to have failed.
3936
// https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=286439 (Vol. 3, page 480)
4037
const MAXIMUM_TRANSACTION_TIME: u8 = 30;
@@ -75,11 +72,11 @@ macro_rules! get_adapter_or_return_error(
7572
match $bl_manager.get_or_create_adapter() {
7673
Some(adapter) => {
7774
if !adapter.is_powered().unwrap_or(false) {
78-
return drop($sender.send(Err(BluetoothError::Type(ADAPTER_NOT_POWERED_ERROR.to_string()))))
75+
return drop($sender.send(Err(BluetoothError::NotFound)))
7976
}
8077
adapter
8178
},
82-
None => return drop($sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
79+
None => return drop($sender.send(Err(BluetoothError::NotFound))),
8380
}
8481
);
8582
);
@@ -106,8 +103,8 @@ fn matches_filter(device: &BluetoothDevice, filter: &BluetoothScanfilter) -> boo
106103
}
107104

108105
// Step 1.
109-
if !filter.get_name().is_empty() {
110-
if device.get_name().ok() != Some(filter.get_name().to_string()) {
106+
if let Some(name) = filter.get_name() {
107+
if device.get_name().ok() != Some(name.to_string()) {
111108
return false;
112109
}
113110
}
@@ -628,6 +625,9 @@ impl BluetoothManager {
628625
device_id: String,
629626
uuid: String,
630627
sender: IpcSender<BluetoothResult<BluetoothServiceMsg>>) {
628+
if !self.cached_devices.contains_key(&device_id) {
629+
return drop(sender.send(Err(BluetoothError::InvalidState)));
630+
}
631631
let mut adapter = get_adapter_or_return_error!(self, sender);
632632
if !self.allowed_services.get(&device_id).map_or(false, |s| s.contains(&uuid)) {
633633
return drop(sender.send(Err(BluetoothError::Security)));
@@ -654,6 +654,9 @@ impl BluetoothManager {
654654
device_id: String,
655655
uuid: Option<String>,
656656
sender: IpcSender<BluetoothResult<BluetoothServicesMsg>>) {
657+
if !self.cached_devices.contains_key(&device_id) {
658+
return drop(sender.send(Err(BluetoothError::InvalidState)));
659+
}
657660
let mut adapter = get_adapter_or_return_error!(self, sender);
658661
let services = match uuid {
659662
Some(ref id) => {
@@ -679,6 +682,10 @@ impl BluetoothManager {
679682
}
680683
}
681684
}
685+
services_vec.retain(|s| !uuid_is_blacklisted(&s.uuid, Blacklist::All) &&
686+
self.allowed_services
687+
.get(&device_id)
688+
.map_or(false, |uuids| uuids.contains(&s.uuid)));
682689
if services_vec.is_empty() {
683690
return drop(sender.send(Err(BluetoothError::NotFound)));
684691
}
@@ -690,9 +697,12 @@ impl BluetoothManager {
690697
service_id: String,
691698
uuid: String,
692699
sender: IpcSender<BluetoothResult<BluetoothServiceMsg>>) {
700+
if !self.cached_services.contains_key(&service_id) {
701+
return drop(sender.send(Err(BluetoothError::InvalidState)));
702+
}
693703
let mut adapter = match self.get_or_create_adapter() {
694704
Some(a) => a,
695-
None => return drop(sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
705+
None => return drop(sender.send(Err(BluetoothError::NotFound))),
696706
};
697707
let device = match self.device_from_service_id(&service_id) {
698708
Some(device) => device,
@@ -721,9 +731,12 @@ impl BluetoothManager {
721731
service_id: String,
722732
uuid: Option<String>,
723733
sender: IpcSender<BluetoothResult<BluetoothServicesMsg>>) {
734+
if !self.cached_services.contains_key(&service_id) {
735+
return drop(sender.send(Err(BluetoothError::InvalidState)));
736+
}
724737
let mut adapter = match self.get_or_create_adapter() {
725738
Some(a) => a,
726-
None => return drop(sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
739+
None => return drop(sender.send(Err(BluetoothError::NotFound))),
727740
};
728741
let device = match self.device_from_service_id(&service_id) {
729742
Some(device) => device,
@@ -747,6 +760,7 @@ impl BluetoothManager {
747760
if let Some(uuid) = uuid {
748761
services_vec.retain(|ref s| s.uuid == uuid);
749762
}
763+
services_vec.retain(|s| !uuid_is_blacklisted(&s.uuid, Blacklist::All));
750764
if services_vec.is_empty() {
751765
return drop(sender.send(Err(BluetoothError::NotFound)));
752766
}
@@ -758,6 +772,9 @@ impl BluetoothManager {
758772
service_id: String,
759773
uuid: String,
760774
sender: IpcSender<BluetoothResult<BluetoothCharacteristicMsg>>) {
775+
if !self.cached_services.contains_key(&service_id) {
776+
return drop(sender.send(Err(BluetoothError::InvalidState)));
777+
}
761778
let mut adapter = get_adapter_or_return_error!(self, sender);
762779
let characteristics = self.get_gatt_characteristics_by_uuid(&mut adapter, &service_id, &uuid);
763780
if characteristics.is_empty() {
@@ -789,6 +806,9 @@ impl BluetoothManager {
789806
service_id: String,
790807
uuid: Option<String>,
791808
sender: IpcSender<BluetoothResult<BluetoothCharacteristicsMsg>>) {
809+
if !self.cached_services.contains_key(&service_id) {
810+
return drop(sender.send(Err(BluetoothError::InvalidState)));
811+
}
792812
let mut adapter = get_adapter_or_return_error!(self, sender);
793813
let characteristics = match uuid {
794814
Some(id) => self.get_gatt_characteristics_by_uuid(&mut adapter, &service_id, &id),
@@ -817,6 +837,7 @@ impl BluetoothManager {
817837
});
818838
}
819839
}
840+
characteristics_vec.retain(|c| !uuid_is_blacklisted(&c.uuid, Blacklist::All));
820841
if characteristics_vec.is_empty() {
821842
return drop(sender.send(Err(BluetoothError::NotFound)));
822843
}
@@ -828,6 +849,9 @@ impl BluetoothManager {
828849
characteristic_id: String,
829850
uuid: String,
830851
sender: IpcSender<BluetoothResult<BluetoothDescriptorMsg>>) {
852+
if !self.cached_characteristics.contains_key(&characteristic_id) {
853+
return drop(sender.send(Err(BluetoothError::InvalidState)));
854+
}
831855
let mut adapter = get_adapter_or_return_error!(self, sender);
832856
let descriptors = self.get_gatt_descriptors_by_uuid(&mut adapter, &characteristic_id, &uuid);
833857
if descriptors.is_empty() {
@@ -848,6 +872,9 @@ impl BluetoothManager {
848872
characteristic_id: String,
849873
uuid: Option<String>,
850874
sender: IpcSender<BluetoothResult<BluetoothDescriptorsMsg>>) {
875+
if !self.cached_characteristics.contains_key(&characteristic_id) {
876+
return drop(sender.send(Err(BluetoothError::InvalidState)));
877+
}
851878
let mut adapter = get_adapter_or_return_error!(self, sender);
852879
let descriptors = match uuid {
853880
Some(id) => self.get_gatt_descriptors_by_uuid(&mut adapter, &characteristic_id, &id),
@@ -865,6 +892,7 @@ impl BluetoothManager {
865892
});
866893
}
867894
}
895+
descriptors_vec.retain(|d| !uuid_is_blacklisted(&d.uuid, Blacklist::All));
868896
if descriptors_vec.is_empty() {
869897
return drop(sender.send(Err(BluetoothError::NotFound)));
870898
}
@@ -879,7 +907,7 @@ impl BluetoothManager {
879907
value = self.get_gatt_descriptor(&mut adapter, &id)
880908
.map(|d| d.read_value().unwrap_or(vec![]));
881909
}
882-
let _ = sender.send(value.ok_or(BluetoothError::NotSupported));
910+
let _ = sender.send(value.ok_or(BluetoothError::InvalidState));
883911
}
884912

885913
fn write_value(&mut self, id: String, value: Vec<u8>, sender: IpcSender<BluetoothResult<bool>>) {
@@ -895,7 +923,7 @@ impl BluetoothManager {
895923
Ok(_) => Ok(true),
896924
Err(_) => return drop(sender.send(Err(BluetoothError::NotSupported))),
897925
},
898-
None => return drop(sender.send(Err(BluetoothError::NotSupported))),
926+
None => return drop(sender.send(Err(BluetoothError::InvalidState))),
899927
};
900928
let _ = sender.send(message);
901929
}

components/bluetooth_traits/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ path = "lib.rs"
1111

1212
[dependencies]
1313
ipc-channel = "0.5"
14+
regex = "0.1.43"
1415
serde = "0.8"
1516
serde_derive = "0.8"
17+
util = {path = "../util"}

components/bluetooth_traits/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
#![feature(proc_macro)]
66

77
extern crate ipc_channel;
8+
extern crate regex;
89
#[macro_use]
910
extern crate serde_derive;
11+
extern crate util;
1012

13+
pub mod blacklist;
1114
pub mod scanfilter;
1215

1316
use ipc_channel::ipc::IpcSender;
@@ -20,6 +23,7 @@ pub enum BluetoothError {
2023
NotFound,
2124
NotSupported,
2225
Security,
26+
InvalidState,
2327
}
2428

2529
#[derive(Deserialize, Serialize)]

components/bluetooth_traits/scanfilter.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ impl ServiceUUIDSequence {
2525

2626
#[derive(Deserialize, Serialize)]
2727
pub struct BluetoothScanfilter {
28-
name: String,
28+
name: Option<String>,
2929
name_prefix: String,
3030
services: ServiceUUIDSequence,
3131
manufacturer_id: Option<u16>,
3232
service_data_uuid: String,
3333
}
3434

3535
impl BluetoothScanfilter {
36-
pub fn new(name: String,
36+
pub fn new(name: Option<String>,
3737
name_prefix: String,
3838
services: Vec<String>,
3939
manufacturer_id: Option<u16>,
@@ -48,8 +48,8 @@ impl BluetoothScanfilter {
4848
}
4949
}
5050

51-
pub fn get_name(&self) -> &str {
52-
&self.name
51+
pub fn get_name(&self) -> Option<&str> {
52+
self.name.as_ref().map(|s| s.as_str())
5353
}
5454

5555
pub fn get_name_prefix(&self) -> &str {
@@ -69,12 +69,12 @@ impl BluetoothScanfilter {
6969
}
7070

7171
pub fn is_empty_or_invalid(&self) -> bool {
72-
(self.name.is_empty() &&
72+
(self.name.is_none() &&
7373
self.name_prefix.is_empty() &&
7474
self.get_services().is_empty() &&
7575
self.manufacturer_id.is_none() &&
7676
self.service_data_uuid.is_empty()) ||
77-
self.name.len() > MAX_NAME_LENGTH ||
77+
self.get_name().unwrap_or("").len() > MAX_NAME_LENGTH ||
7878
self.name_prefix.len() > MAX_NAME_LENGTH
7979
}
8080
}

components/script/dom/bluetooth.rs

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,34 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted};
65
use bluetooth_traits::{BluetoothError, BluetoothMethodMsg};
6+
use bluetooth_traits::blacklist::{Blacklist, uuid_is_blacklisted};
77
use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence};
88
use bluetooth_traits::scanfilter::{RequestDeviceoptions, ServiceUUIDSequence};
99
use core::clone::Clone;
10+
use dom::bindings::cell::DOMRefCell;
1011
use dom::bindings::codegen::Bindings::BluetoothBinding::{self, BluetoothMethods, BluetoothRequestDeviceFilter};
1112
use dom::bindings::codegen::Bindings::BluetoothBinding::RequestDeviceOptions;
12-
use dom::bindings::error::Error::{self, Security, Type};
13+
use dom::bindings::error::Error::{self, NotFound, Security, Type};
1314
use dom::bindings::error::Fallible;
14-
use dom::bindings::js::Root;
15+
use dom::bindings::js::{JS, MutHeap, Root};
1516
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
1617
use dom::bindings::str::DOMString;
1718
use dom::bluetoothadvertisingdata::BluetoothAdvertisingData;
1819
use dom::bluetoothdevice::BluetoothDevice;
20+
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
21+
use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor;
22+
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
1923
use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID};
2024
use dom::globalscope::GlobalScope;
2125
use dom::promise::Promise;
2226
use ipc_channel::ipc::{self, IpcSender};
2327
use js::conversions::ToJSValConvertible;
28+
use std::collections::HashMap;
2429
use std::rc::Rc;
2530

2631
const FILTER_EMPTY_ERROR: &'static str = "'filters' member, if present, must be nonempty to find any devices.";
2732
const FILTER_ERROR: &'static str = "A filter must restrict the devices in some way.";
28-
const FILTER_NAME_TOO_LONG_ERROR: &'static str = "A 'name' or 'namePrefix' can't be longer then 29 bytes.";
2933
// 248 is the maximum number of UTF-8 code units in a Bluetooth Device Name.
3034
const MAX_DEVICE_NAME_LENGTH: usize = 248;
3135
// A device name can never be longer than 29 bytes.
@@ -43,12 +47,20 @@ const OPTIONS_ERROR: &'static str = "Fields of 'options' conflict with each othe
4347
#[dom_struct]
4448
pub struct Bluetooth {
4549
reflector_: Reflector,
50+
device_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothDevice>>>>,
51+
service_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTService>>>>,
52+
characteristic_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTCharacteristic>>>>,
53+
descriptor_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTDescriptor>>>>,
4654
}
4755

4856
impl Bluetooth {
4957
pub fn new_inherited() -> Bluetooth {
5058
Bluetooth {
5159
reflector_: Reflector::new(),
60+
device_instance_map: DOMRefCell::new(HashMap::new()),
61+
service_instance_map: DOMRefCell::new(HashMap::new()),
62+
characteristic_instance_map: DOMRefCell::new(HashMap::new()),
63+
descriptor_instance_map: DOMRefCell::new(HashMap::new()),
5264
}
5365
}
5466

@@ -58,6 +70,19 @@ impl Bluetooth {
5870
BluetoothBinding::Wrap)
5971
}
6072

73+
pub fn get_service_map(&self) -> &DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTService>>>> {
74+
&self.service_instance_map
75+
}
76+
77+
pub fn get_characteristic_map(&self)
78+
-> &DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTCharacteristic>>>> {
79+
&self.characteristic_instance_map
80+
}
81+
82+
pub fn get_descriptor_map(&self) -> &DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTDescriptor>>>> {
83+
&self.descriptor_instance_map
84+
}
85+
6186
fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
6287
self.global().as_window().bluetooth_thread()
6388
}
@@ -103,15 +128,21 @@ impl Bluetooth {
103128
// Step 12-13.
104129
match device {
105130
Ok(device) => {
106-
let global = self.global();
107-
let ad_data = BluetoothAdvertisingData::new(&global,
131+
let mut device_instance_map = self.device_instance_map.borrow_mut();
132+
if let Some(existing_device) = device_instance_map.get(&device.id.clone()) {
133+
return Ok(existing_device.get());
134+
}
135+
let ad_data = BluetoothAdvertisingData::new(&self.global(),
108136
device.appearance,
109137
device.tx_power,
110138
device.rssi);
111-
Ok(BluetoothDevice::new(&global,
112-
DOMString::from(device.id),
113-
device.name.map(DOMString::from),
114-
&ad_data))
139+
let bt_device = BluetoothDevice::new(&self.global(),
140+
DOMString::from(device.id.clone()),
141+
device.name.map(DOMString::from),
142+
&ad_data,
143+
&self);
144+
device_instance_map.insert(device.id, MutHeap::new(&bt_device));
145+
Ok(bt_device)
115146
},
116147
Err(error) => {
117148
Err(Error::from(error))
@@ -213,13 +244,13 @@ fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter) -> Fallible<Blueto
213244
return Err(Type(NAME_TOO_LONG_ERROR.to_owned()));
214245
}
215246
if name.len() > MAX_FILTER_NAME_LENGTH {
216-
return Err(Type(FILTER_NAME_TOO_LONG_ERROR.to_owned()));
247+
return Err(NotFound);
217248
}
218249

219250
// Step 2.4.4.2.
220-
name.to_string()
251+
Some(name.to_string())
221252
},
222-
None => String::new(),
253+
None => None,
223254
};
224255

225256
// Step 2.4.5.
@@ -233,7 +264,7 @@ fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter) -> Fallible<Blueto
233264
return Err(Type(NAME_TOO_LONG_ERROR.to_owned()));
234265
}
235266
if name_prefix.len() > MAX_FILTER_NAME_LENGTH {
236-
return Err(Type(FILTER_NAME_TOO_LONG_ERROR.to_owned()));
267+
return Err(NotFound);
237268
}
238269

239270
// Step 2.4.5.2.
@@ -289,6 +320,7 @@ impl From<BluetoothError> for Error {
289320
BluetoothError::NotFound => Error::NotFound,
290321
BluetoothError::NotSupported => Error::NotSupported,
291322
BluetoothError::Security => Error::Security,
323+
BluetoothError::InvalidState => Error::InvalidState,
292324
}
293325
}
294326
}

0 commit comments

Comments
 (0)