Skip to content

Commit

Permalink
Move extra permission data to window
Browse files Browse the repository at this point in the history
  • Loading branch information
dati91 committed Feb 13, 2017
1 parent b1d388a commit d5cc10a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 30 deletions.
72 changes: 46 additions & 26 deletions components/script/dom/bluetooth.rs
Expand Up @@ -25,20 +25,21 @@ 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};
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;
Expand All @@ -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<BluetoothPermissionData> =
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<AllowedBluetoothDevice> {
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 {
Expand All @@ -100,6 +79,46 @@ impl Clone for AllowedBluetoothDevice {
}
}

#[derive(HeapSizeOf, JSTraceable)]
pub struct BluetoothExtraPermissionData {
permission_data: DOMRefCell<BluetoothPermissionData>,
}

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<AllowedBluetoothDevice> {
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<T: AsyncBluetoothListener + DomObject> {
promise: Option<TrustedPromise>,
receiver: Trusted<T>,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
5 changes: 3 additions & 2 deletions components/script/dom/bluetoothdevice.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -228,7 +228,8 @@ impl BluetoothDeviceMethods for BluetoothDevice {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-gatt
fn GetGatt(&self) -> Option<Root<BluetoothRemoteGATTServer>> {
// 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.
Expand Down
4 changes: 2 additions & 2 deletions components/script/dom/bluetoothpermissionresult.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions components/script/dom/window.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -209,6 +210,8 @@ pub struct Window {
#[ignore_heap_size_of = "channels are hard"]
bluetooth_thread: IpcSender<BluetoothRequest>,

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<Rect<Au>>,
Expand Down Expand Up @@ -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<ParseErrorReporter + Send> {
self.error_reporter.clone()
}
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit d5cc10a

Please sign in to comment.