From d5cc10a63608c13c732663ebb94068a9beba632f Mon Sep 17 00:00:00 2001 From: Attila Dusnoki Date: Mon, 13 Feb 2017 13:44:21 +0100 Subject: [PATCH] Move extra permission data to window --- components/script/dom/bluetooth.rs | 72 ++++++++++++------- components/script/dom/bluetoothdevice.rs | 5 +- .../script/dom/bluetoothpermissionresult.rs | 4 +- components/script/dom/window.rs | 8 +++ 4 files changed, 59 insertions(+), 30 deletions(-) diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index 0c77ee1ba90a..d97e6dfb6bf8 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -25,6 +25,7 @@ use dom::bindings::js::{JS, Root}; use dom::bindings::refcounted::{Trusted, TrustedPromise}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; +use dom::bindings::trace::JSTraceable; use dom::bluetoothdevice::BluetoothDevice; use dom::bluetoothpermissionresult::BluetoothPermissionResult; use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID, UUID}; @@ -32,13 +33,13 @@ use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::permissions::{get_descriptor_permission_state, PermissionAlgorithm}; use dom::promise::Promise; +use heapsize::{HeapSizeOf, heap_size_of}; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use js::conversions::ConversionResult; use js::jsapi::{JSAutoCompartment, JSContext, JSObject}; use js::jsval::{ObjectValue, UndefinedValue}; use script_thread::Runnable; -use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; use std::str::FromStr; @@ -59,28 +60,6 @@ const OPTIONS_ERROR: &'static str = "Fields of 'options' conflict with each othe Either 'acceptAllDevices' member must be true, or 'filters' member must be set to a value."; const BT_DESC_CONVERSION_ERROR: &'static str = "Can't convert to an IDL value of type BluetoothPermissionDescriptor"; - -thread_local!(pub static EXTRA_PERMISSION_DATA: RefCell = - RefCell::new(BluetoothPermissionData { allowedDevices: Vec::new() })); - -pub fn add_new_allowed_device(allowed_device: AllowedBluetoothDevice) { - EXTRA_PERMISSION_DATA.with(|epdata| { - epdata.borrow_mut().allowedDevices.push(allowed_device); - }); -} - -fn get_allowed_devices() -> Vec { - EXTRA_PERMISSION_DATA.with(|epdata| { - epdata.borrow().allowedDevices.clone() - }) -} - -pub fn allowed_devices_contains_id(id: DOMString) -> bool { - EXTRA_PERMISSION_DATA.with(|epdata| { - epdata.borrow_mut().allowedDevices.iter().any(|d| d.deviceId == id) - }) -} - impl Clone for StringOrStringSequence { fn clone(&self) -> StringOrStringSequence { match self { @@ -100,6 +79,46 @@ impl Clone for AllowedBluetoothDevice { } } +#[derive(HeapSizeOf, JSTraceable)] +pub struct BluetoothExtraPermissionData { + permission_data: DOMRefCell, +} + +impl BluetoothExtraPermissionData { + pub fn new() -> BluetoothExtraPermissionData { + BluetoothExtraPermissionData { + permission_data: DOMRefCell::new(BluetoothPermissionData { allowedDevices: Vec::new() }), + } + } + + pub fn add_new_allowed_device(&self, allowed_device: AllowedBluetoothDevice) { + self.permission_data.borrow_mut().allowedDevices.push(allowed_device); + } + + fn get_allowed_devices(&self) -> Vec { + self.permission_data.borrow().allowedDevices.clone() + } + + pub fn allowed_devices_contains_id(&self, id: DOMString) -> bool { + self.permission_data.borrow_mut().allowedDevices.iter().any(|d| d.deviceId == id) + } +} + +impl HeapSizeOf for BluetoothPermissionData { + #[allow(unsafe_code)] + fn heap_size_of_children(&self) -> usize { + unsafe { heap_size_of(self.allowedDevices.as_ptr() as *const _) } + } +} + +#[allow(unsafe_code)] +unsafe impl JSTraceable for BluetoothPermissionData { + #[inline] + unsafe fn trace(&self, _: *mut ::js::jsapi::JSTracer) { + // Do nothing + } +} + struct BluetoothContext { promise: Option, receiver: Trusted, @@ -531,7 +550,8 @@ impl AsyncBluetoothListener for Bluetooth { device.name.map(DOMString::from), &self); device_instance_map.insert(device.id.clone(), JS::from_ref(&bt_device)); - add_new_allowed_device( + + self.global().as_window().bluetooth_extra_permission_data().add_new_allowed_device( AllowedBluetoothDevice { // TODO fix this // allowedServices only relevant if the device store it as an inter slot as well @@ -597,7 +617,7 @@ impl PermissionAlgorithm for Bluetooth { // https://webbluetoothcg.github.io/web-bluetooth/#dictdef-bluetoothpermissiondata // Step 5. - let allowed_devices = get_allowed_devices(); + let allowed_devices = status.global().as_window().bluetooth_extra_permission_data().get_allowed_devices(); let bluetooth = status.get_bluetooth(); let device_map = bluetooth.get_device_map().borrow(); @@ -677,7 +697,7 @@ impl PermissionAlgorithm for Bluetooth { // https://webbluetoothcg.github.io/web-bluetooth/#revoke-bluetooth-access fn permission_revoke(_descriptor: &BluetoothPermissionDescriptor, status: &BluetoothPermissionResult) { // Step 1. - let allowed_devices = get_allowed_devices(); + let allowed_devices = status.global().as_window().bluetooth_extra_permission_data().get_allowed_devices(); // Step 2. let bluetooth = status.get_bluetooth(); let device_map = bluetooth.get_device_map().borrow(); diff --git a/components/script/dom/bluetoothdevice.rs b/components/script/dom/bluetoothdevice.rs index 16892f360130..d33aab9be974 100644 --- a/components/script/dom/bluetoothdevice.rs +++ b/components/script/dom/bluetoothdevice.rs @@ -15,7 +15,7 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; -use dom::bluetooth::{allowed_devices_contains_id, AsyncBluetoothListener, Bluetooth, response_async}; +use dom::bluetooth::{AsyncBluetoothListener, Bluetooth, response_async}; use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties; use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic; use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor; @@ -228,7 +228,8 @@ impl BluetoothDeviceMethods for BluetoothDevice { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-gatt fn GetGatt(&self) -> Option> { // Step 1. - if allowed_devices_contains_id(self.id.clone()) && !self.is_represented_device_null() { + if self.global().as_window().bluetooth_extra_permission_data() + .allowed_devices_contains_id(self.id.clone()) && !self.is_represented_device_null() { return Some(self.get_gatt()) } // Step 2. diff --git a/components/script/dom/bluetoothpermissionresult.rs b/components/script/dom/bluetoothpermissionresult.rs index 132d886a06cf..993df5f65245 100644 --- a/components/script/dom/bluetoothpermissionresult.rs +++ b/components/script/dom/bluetoothpermissionresult.rs @@ -15,7 +15,7 @@ use dom::bindings::error::Error; use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; -use dom::bluetooth::{add_new_allowed_device, AsyncBluetoothListener, Bluetooth}; +use dom::bluetooth::{AsyncBluetoothListener, Bluetooth}; use dom::bluetoothdevice::BluetoothDevice; use dom::globalscope::GlobalScope; use dom::permissionstatus::PermissionStatus; @@ -106,7 +106,7 @@ impl AsyncBluetoothListener for BluetoothPermissionResult { device.name.map(DOMString::from), &bluetooth); device_instance_map.insert(device.id.clone(), JS::from_ref(&bt_device)); - add_new_allowed_device( + self.global().as_window().bluetooth_extra_permission_data().add_new_allowed_device( AllowedBluetoothDevice { // TODO fix this // allowedServices only relevant if the device store it as an internal slot as well diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index fe9bab6a5e6b..18cd5a862462 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -26,6 +26,7 @@ use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::utils::{GlobalStaticData, WindowProxyHandler}; +use dom::bluetooth::BluetoothExtraPermissionData; use dom::browsingcontext::BrowsingContext; use dom::crypto::Crypto; use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner}; @@ -209,6 +210,8 @@ pub struct Window { #[ignore_heap_size_of = "channels are hard"] bluetooth_thread: IpcSender, + bluetooth_extra_permission_data: BluetoothExtraPermissionData, + /// An enlarged rectangle around the page contents visible in the viewport, used /// to prevent creating display list items for content that is far away from the viewport. page_clip_rect: Cell>, @@ -313,6 +316,10 @@ impl Window { self.bluetooth_thread.clone() } + pub fn bluetooth_extra_permission_data(&self) -> &BluetoothExtraPermissionData { + &self.bluetooth_extra_permission_data + } + pub fn css_error_reporter(&self) -> Box { self.error_reporter.clone() } @@ -1678,6 +1685,7 @@ impl Window { dom_static: GlobalStaticData::new(), js_runtime: DOMRefCell::new(Some(runtime.clone())), bluetooth_thread: bluetooth_thread, + bluetooth_extra_permission_data: BluetoothExtraPermissionData::new(), page_clip_rect: Cell::new(max_rect()), resize_event: Cell::new(None), layout_chan: layout_chan,