Add Bluetooth IPC support

This commit is contained in:
fokinv 2016-03-17 11:57:20 +01:00 committed by Attila Dusnoki
parent 9d55748de2
commit 9825ea41b4
20 changed files with 1037 additions and 46 deletions

View file

@ -36,6 +36,7 @@ use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, NavigationD
use msg::constellation_msg::{SubpageId, WindowSizeData, WindowSizeType};
use msg::constellation_msg::{self, ConstellationChan, PanicMsg};
use msg::webdriver_msg;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::ImageCacheThread;
use net_traits::storage_thread::{StorageThread, StorageThreadMsg};
use net_traits::{self, ResourceThread};
@ -123,6 +124,9 @@ pub struct Constellation<LTF, STF> {
/// A channel through which messages can be sent to the developer tools.
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
/// A channel through which messages can be sent to the bluetooth thread.
bluetooth_thread: IpcSender<BluetoothMethodMsg>,
/// A channel through which messages can be sent to the storage thread.
storage_thread: StorageThread,
@ -197,6 +201,8 @@ pub struct InitialConstellationState {
pub compositor_proxy: Box<CompositorProxy + Send>,
/// A channel to the developer tools, if applicable.
pub devtools_chan: Option<Sender<DevtoolsControlMsg>>,
/// A channel to the bluetooth thread.
pub bluetooth_thread: IpcSender<BluetoothMethodMsg>,
/// A channel to the image cache thread.
pub image_cache_thread: ImageCacheThread,
/// A channel to the font cache thread.
@ -338,6 +344,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
panic_receiver: panic_receiver,
compositor_proxy: state.compositor_proxy,
devtools_chan: state.devtools_chan,
bluetooth_thread: state.bluetooth_thread,
resource_thread: state.resource_thread,
image_cache_thread: state.image_cache_thread,
font_cache_thread: state.font_cache_thread,
@ -424,6 +431,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
scheduler_chan: self.scheduler_chan.clone(),
compositor_proxy: self.compositor_proxy.clone_compositor_proxy(),
devtools_chan: self.devtools_chan.clone(),
bluetooth_thread: self.bluetooth_thread.clone(),
image_cache_thread: self.image_cache_thread.clone(),
font_cache_thread: self.font_cache_thread.clone(),
resource_thread: self.resource_thread.clone(),
@ -840,6 +848,9 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
if let Err(e) = self.storage_thread.send(StorageThreadMsg::Exit) {
warn!("Exit storage thread failed ({})", e);
}
if let Err(e) = self.bluetooth_thread.send(BluetoothMethodMsg::Exit) {
warn!("Exit bluetooth thread failed ({})", e);
}
self.font_cache_thread.exit();
self.compositor_proxy.send(ToCompositorMsg::ShutdownComplete);
}

View file

@ -18,6 +18,7 @@ use msg::constellation_msg::{ConstellationChan, PanicMsg, FrameId, PipelineId, S
use msg::constellation_msg::{LoadData, WindowSizeData};
use msg::constellation_msg::{PipelineNamespaceId};
use net_traits::ResourceThread;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::ImageCacheThread;
use net_traits::storage_thread::StorageThread;
use profile_traits::mem as profile_mem;
@ -92,6 +93,8 @@ pub struct InitialPipelineState {
pub compositor_proxy: Box<CompositorProxy + 'static + Send>,
/// A channel to the developer tools, if applicable.
pub devtools_chan: Option<Sender<DevtoolsControlMsg>>,
/// A channel to the bluetooth thread.
pub bluetooth_thread: IpcSender<BluetoothMethodMsg>,
/// A channel to the image cache thread.
pub image_cache_thread: ImageCacheThread,
/// A channel to the font cache thread.
@ -214,6 +217,7 @@ impl Pipeline {
constellation_chan: state.constellation_chan,
scheduler_chan: state.scheduler_chan,
devtools_chan: script_to_devtools_chan,
bluetooth_thread: state.bluetooth_thread,
image_cache_thread: state.image_cache_thread,
font_cache_thread: state.font_cache_thread.clone(),
resource_thread: state.resource_thread,
@ -390,6 +394,7 @@ pub struct UnprivilegedPipelineContent {
scheduler_chan: IpcSender<TimerEventRequest>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
script_to_compositor_chan: IpcSender<ScriptToCompositorMsg>,
bluetooth_thread: IpcSender<BluetoothMethodMsg>,
image_cache_thread: ImageCacheThread,
font_cache_thread: FontCacheThread,
resource_thread: ResourceThread,
@ -430,6 +435,7 @@ impl UnprivilegedPipelineContent {
layout_to_constellation_chan: self.layout_to_constellation_chan.clone(),
scheduler_chan: self.scheduler_chan.clone(),
panic_chan: self.panic_chan.clone(),
bluetooth_thread: self.bluetooth_thread.clone(),
resource_thread: self.resource_thread,
storage_thread: self.storage_thread.clone(),
image_cache_thread: self.image_cache_thread.clone(),

View file

@ -17,6 +17,7 @@ plugins = {path = "../plugins"}
msg = {path = "../msg"}
ipc-channel = {git = "https://github.com/servo/ipc-channel"}
webrender_traits = {git = "https://github.com/servo/webrender_traits"}
device = {git = "https://github.com/servo/devices"}
cookie = { version = "0.2.4", features = [ "serialize-rustc" ] }
flate2 = "0.2.0"
hyper = { version = "0.9", features = [ "serde-serialization" ] }

View file

@ -0,0 +1,522 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use device::bluetooth::BluetoothAdapter;
use device::bluetooth::BluetoothDevice;
use device::bluetooth::BluetoothGATTCharacteristic;
use device::bluetooth::BluetoothGATTDescriptor;
use device::bluetooth::BluetoothGATTService;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use net_traits::bluetooth_thread::{BluetoothMethodMsg, BluetoothObjectMsg};
use std::borrow::ToOwned;
use std::collections::HashMap;
use std::string::String;
use util::thread::spawn_named;
macro_rules! send_error(
($sender:expr, $error:expr) => (
return $sender.send(BluetoothObjectMsg::Error { error: String::from($error) }).unwrap();
);
);
macro_rules! check_cache(
($cache:expr, $key:expr) => (
if $cache.contains_key($key) {
return $cache.get($key);
}
);
);
pub trait BluetoothThreadFactory {
fn new() -> Self;
}
impl BluetoothThreadFactory for IpcSender<BluetoothMethodMsg> {
fn new() -> IpcSender<BluetoothMethodMsg> {
let (sender, receiver) = ipc::channel().unwrap();
let adapter = match BluetoothAdapter::init() {
Ok(a) => Some(a),
Err(_) => None,
};
spawn_named("BluetoothThread".to_owned(), move || {
BluetoothManager::new(receiver, adapter).start();
});
sender
}
}
pub struct BluetoothManager {
receiver: IpcReceiver<BluetoothMethodMsg>,
adapter: Option<BluetoothAdapter>,
service_to_device: HashMap<String, String>,
characteristic_to_service: HashMap<String, String>,
descriptor_to_characteristic: HashMap<String, String>,
cached_devices: HashMap<String, BluetoothDevice>,
cached_services: HashMap<String, BluetoothGATTService>,
cached_characteristics: HashMap<String, BluetoothGATTCharacteristic>,
cached_descriptors: HashMap<String, BluetoothGATTDescriptor>,
}
impl BluetoothManager {
pub fn new (receiver: IpcReceiver<BluetoothMethodMsg>, adapter: Option<BluetoothAdapter>) -> BluetoothManager {
BluetoothManager {
receiver: receiver,
adapter: adapter,
service_to_device: HashMap::new(),
characteristic_to_service: HashMap::new(),
descriptor_to_characteristic: HashMap::new(),
cached_devices: HashMap::new(),
cached_services: HashMap::new(),
cached_characteristics: HashMap::new(),
cached_descriptors: HashMap::new(),
}
}
fn start(&mut self) {
loop {
match self.receiver.recv().unwrap() {
BluetoothMethodMsg::RequestDevice(sender) => {
self.request_device(sender)
}
BluetoothMethodMsg::GATTServerConnect(device_id, sender) => {
self.gatt_server_connect(device_id, sender)
}
BluetoothMethodMsg::GATTServerDisconnect(device_id, sender) => {
self.gatt_server_disconnect(device_id, sender)
}
BluetoothMethodMsg::GetPrimaryService(device_id, sender) => {
self.get_primary_service(device_id, sender)
}
BluetoothMethodMsg::GetCharacteristic(service_id, sender) => {
self.get_characteristic(service_id, sender)
}
BluetoothMethodMsg::GetDescriptor(characteristic_id, sender) => {
self.get_descriptor(characteristic_id, sender)
}
BluetoothMethodMsg::ReadValue(id, sender) => {
self.read_value(id, sender)
}
BluetoothMethodMsg::WriteValue(id, value, sender) => {
self.write_value(id, value, sender)
}
BluetoothMethodMsg::Exit => {
break
}
}
}
}
// Adapter
fn get_adapter(&mut self) -> Option<BluetoothAdapter> {
if self.adapter.is_none()
|| self.adapter.clone().unwrap().get_address().is_err() {
self.adapter = BluetoothAdapter::init().ok();
}
self.adapter.clone()
}
// Device
fn get_devices(&mut self, adapter: &mut BluetoothAdapter) -> Vec<BluetoothDevice> {
let devices = adapter.get_devices().unwrap_or(vec!());
for device in &devices {
self.cached_devices.insert(device.get_address().unwrap_or("".to_owned()), device.clone());
}
devices
}
fn get_device(&mut self, adapter: &mut BluetoothAdapter, device_id: &str) -> Option<&BluetoothDevice> {
check_cache!(self.cached_devices, device_id);
// Update cache
self.get_devices(adapter);
check_cache!(self.cached_devices, device_id);
None
}
// Service
fn get_gatt_services(&mut self, adapter: &mut BluetoothAdapter, device_id: &str) -> Vec<BluetoothGATTService> {
let services = match self.get_device(adapter, device_id) {
Some(d) => d.get_gatt_services().unwrap_or(vec!()),
None => vec!(),
};
for service in &services {
self.cached_services.insert(service.get_object_path(), service.clone());
self.service_to_device.insert(service.get_object_path(), device_id.to_owned());
}
services
}
fn get_gatt_service(&mut self,
adapter: &mut BluetoothAdapter,
service_id: &str)
-> Option<&BluetoothGATTService> {
check_cache!(self.cached_services, service_id);
let device_id = match self.service_to_device.get_mut(service_id) {
Some(d) => d.clone(),
None => return None,
};
// Update cache
self.get_gatt_services(adapter, &device_id);
check_cache!(self.cached_services, service_id);
None
}
#[allow(dead_code)]
fn get_gatt_service_by_uuid(&mut self,
adapter: &mut BluetoothAdapter,
device_id: &str,
service_uuid: &str)
-> Option<BluetoothGATTService> {
for service in self.cached_services.values() {
if service.get_uuid().unwrap_or("".to_owned()) == service_uuid {
return Some(service.clone());
}
}
// Update cache
let services = self.get_gatt_services(adapter, device_id);
for service in services {
if service.get_uuid().unwrap_or("".to_owned()) == service_uuid {
return Some(service.clone());
}
}
None
}
// Characteristic
fn get_gatt_characteristics(&mut self,
adapter: &mut BluetoothAdapter,
service_id: &str)
-> Vec<BluetoothGATTCharacteristic> {
let characteristics = match self.get_gatt_service(adapter, service_id) {
Some(s) => s.get_gatt_characteristics().unwrap_or(vec!()),
None => vec!(),
};
for characteristic in &characteristics {
self.cached_characteristics.insert(characteristic.get_object_path(), characteristic.clone());
self.characteristic_to_service.insert(characteristic.get_object_path(), service_id.to_owned());
}
characteristics
}
fn get_gatt_characteristic(&mut self,
adapter: &mut BluetoothAdapter,
characteristic_id: &str)
-> Option<&BluetoothGATTCharacteristic> {
check_cache!(self.cached_characteristics, characteristic_id);
let service_id = match self.characteristic_to_service.get_mut(characteristic_id) {
Some(s) => s.clone(),
None => return None,
};
// Update cache
self.get_gatt_characteristics(adapter, &service_id);
check_cache!(self.cached_characteristics, characteristic_id);
None
}
#[allow(dead_code)]
fn get_gatt_characteristic_by_uuid(&mut self,
adapter: &mut BluetoothAdapter,
service_id: &str,
characteristic_uuid: &str)
-> Option<BluetoothGATTCharacteristic> {
for characteristic in self.cached_characteristics.values() {
if characteristic.get_uuid().unwrap_or("".to_owned()) == characteristic_uuid {
return Some(characteristic.clone());
}
}
// Update cache
let characteristics = self.get_gatt_characteristics(adapter, service_id);
for characteristic in characteristics {
if characteristic.get_uuid().unwrap_or("".to_owned()) == characteristic_uuid {
return Some(characteristic.clone());
}
}
None
}
fn get_characteristic_properties(&self, characteristic: &BluetoothGATTCharacteristic) -> [bool; 9] {
let mut props = [false; 9];
let flags = characteristic.get_flags().unwrap_or(vec!());
for flag in flags {
match flag.as_ref() {
"broadcast" => props[0] = true,
"read" => props[1] = true,
"write_without_response" => props[2] = true,
"write" => props[3] = true,
"notify" => props[4] = true,
"indicate" => props[5] = true,
"authenticated_signed_writes" => props[6] = true,
"reliable_write" => props[7] = true,
"writable_auxiliaries" => props[8] = true,
_ => (),
}
}
props
}
// Descriptor
fn get_gatt_descriptors(&mut self,
adapter: &mut BluetoothAdapter,
characteristic_id: &str)
-> Vec<BluetoothGATTDescriptor> {
let descriptors = match self.get_gatt_characteristic(adapter, characteristic_id) {
Some(c) => c.get_gatt_descriptors().unwrap_or(vec!()),
None => vec!(),
};
for descriptor in &descriptors {
self.cached_descriptors.insert(descriptor.get_object_path(), descriptor.clone());
self.descriptor_to_characteristic.insert(descriptor.get_object_path(), characteristic_id.to_owned());
}
descriptors
}
fn get_gatt_descriptor(&mut self,
adapter: &mut BluetoothAdapter,
descriptor_id: &str)
-> Option<&BluetoothGATTDescriptor> {
check_cache!(self.cached_descriptors, descriptor_id);
let characteristic_id = match self.descriptor_to_characteristic.get_mut(descriptor_id) {
Some(c) => c.clone(),
None => return None,
};
// Update cache
self.get_gatt_descriptors(adapter, &characteristic_id);
check_cache!(self.cached_descriptors, descriptor_id);
None
}
#[allow(dead_code)]
fn get_gatt_descriptor_by_uuid(&mut self,
adapter: &mut BluetoothAdapter,
characteristic_id: &str,
descriptor_uuid: &str)
-> Option<BluetoothGATTDescriptor> {
for descriptor in self.cached_descriptors.values() {
if descriptor.get_uuid().unwrap_or("".to_owned()) == descriptor_uuid {
return Some(descriptor.clone());
}
}
// Update cache
let descriptors = self.get_gatt_descriptors(adapter, characteristic_id);
for descriptor in descriptors {
if descriptor.get_uuid().unwrap_or("".to_owned()) == descriptor_uuid {
return Some(descriptor.clone());
}
}
None
}
// Methods
fn request_device(&mut self, sender: IpcSender<BluetoothObjectMsg>) {
let mut adapter = match self.get_adapter() {
Some(a) => a,
None => send_error!(sender, "No adapter found"),
};
let devices = self.get_devices(&mut adapter);
if devices.is_empty() {
send_error!(sender, "No device found");
}
//TODO select the proper device
let device = &devices[0];
let message = BluetoothObjectMsg::BluetoothDevice {
id: device.get_address().unwrap_or("".to_owned()),
name: device.get_name().ok(),
device_class: device.get_class().ok(),
vendor_id_source: device.get_vendor_id_source().ok(),
vendor_id: device.get_vendor_id().ok(),
product_id: device.get_product_id().ok(),
product_version: device.get_device_id().ok(),
appearance: device.get_appearance().ok(),
tx_power: match device.get_tx_power() {
Ok(p) => Some(p as i8),
Err(_) => None,
},
rssi: match device.get_rssi() {
Ok(p) => Some(p as i8),
Err(_) => None,
}
};
sender.send(message).unwrap();
}
pub fn gatt_server_connect(&mut self, device_id: String, sender: IpcSender<BluetoothObjectMsg>) {
let mut adapter = match self.get_adapter() {
Some(a) => a,
None => send_error!(sender, "No adapter found"),
};
let connected = match self.get_device(&mut adapter, &device_id) {
Some(d) => {
if d.is_connected().unwrap_or(false) {
true
} else {
!d.connect().is_err()
}
}
None => send_error!(sender, "No device found"),
};
let message = BluetoothObjectMsg::BluetoothServer {
connected: connected
};
sender.send(message).unwrap();
}
pub fn gatt_server_disconnect(&mut self, device_id: String, sender: IpcSender<BluetoothObjectMsg>) {
let mut adapter = match self.get_adapter() {
Some(a) => a,
None => send_error!(sender, "No adapter found"),
};
let connected = match self.get_device(&mut adapter, &device_id) {
Some(d) => {
if d.is_connected().unwrap_or(false) {
d.disconnect().is_err()
} else {
false
}
}
None => send_error!(sender, "No device found"),
};
let message = BluetoothObjectMsg::BluetoothServer {
connected: connected
};
sender.send(message).unwrap();
}
pub fn get_primary_service(&mut self, device_id: String, sender: IpcSender<BluetoothObjectMsg>) {
let mut adapter = match self.get_adapter() {
Some(a) => a,
None => send_error!(sender, "No adapter found"),
};
let services = self.get_gatt_services(&mut adapter, &device_id);
if services.is_empty() {
send_error!(sender, "No service found");
}
for service in services {
if service.is_primary().unwrap_or(false) {
let message = BluetoothObjectMsg::BluetoothService {
uuid: service.get_uuid().unwrap_or("".to_owned()),
is_primary: true,
instance_id: service.get_object_path()
};
sender.send(message).unwrap();
return;
}
}
send_error!(sender, "No primary service found");
}
pub fn get_characteristic(&mut self, service_id: String, sender: IpcSender<BluetoothObjectMsg>) {
let mut adapter = match self.get_adapter() {
Some(a) => a,
None => send_error!(sender, "No adapter found"),
};
let characteristics = self.get_gatt_characteristics(&mut adapter, &service_id);
if characteristics.is_empty() {
send_error!(sender, "No characteristic found");
}
let characteristic = &characteristics[0];
let properties = self.get_characteristic_properties(&characteristic);
let message = BluetoothObjectMsg::BluetoothCharacteristic {
uuid: characteristic.get_uuid().unwrap_or("".to_owned()),
instance_id: characteristic.get_object_path(),
broadcast: properties[0],
read: properties[1],
write_without_response: properties[2],
write: properties[3],
notify: properties[4],
indicate: properties[5],
authenticated_signed_writes: properties[6],
reliable_write: properties[7],
writable_auxiliaries: properties[8]
};
sender.send(message).unwrap();
}
pub fn get_descriptor(&mut self, characteristic_id: String, sender: IpcSender<BluetoothObjectMsg>) {
let mut adapter = match self.get_adapter() {
Some(a) => a,
None => send_error!(sender, "No adapter found"),
};
let descriptors = self.get_gatt_descriptors(&mut adapter, &characteristic_id);
if descriptors.is_empty() {
send_error!(sender, "No descriptor found");
}
let descriptor = &descriptors[0];
let message = BluetoothObjectMsg::BluetoothDescriptor {
uuid: descriptor.get_uuid().unwrap_or("".to_owned()),
instance_id: descriptor.get_object_path(),
};
sender.send(message).unwrap();
}
pub fn read_value(&mut self, id: String, sender: IpcSender<BluetoothObjectMsg>) {
let mut adapter = match self.get_adapter() {
Some(a) => a,
None => send_error!(sender, "No adapter found"),
};
let mut value = match self.get_gatt_characteristic(&mut adapter, &id) {
Some(c) => Some(c.read_value().unwrap_or(vec!())),
None => None,
};
if value.is_none() {
value = match self.get_gatt_descriptor(&mut adapter, &id) {
Some(d) => Some(d.read_value().unwrap_or(vec!())),
None => None,
};
}
let message = match value {
Some(v) => BluetoothObjectMsg::BluetoothReadValue { value: v },
None => send_error!(sender, "No characteristic or descriptor found with that id"),
};
sender.send(message).unwrap();
}
pub fn write_value(&mut self, id: String, value: Vec<u8>, sender: IpcSender<BluetoothObjectMsg>) {
let mut adapter = match self.get_adapter() {
Some(a) => a,
None => send_error!(sender, "No adapter found"),
};
let mut result = match self.get_gatt_characteristic(&mut adapter, &id) {
Some(c) => Some(c.write_value(value.clone())),
None => None,
};
if result.is_none() {
result = match self.get_gatt_descriptor(&mut adapter, &id) {
Some(d) => Some(d.write_value(value.clone())),
None => None,
};
}
let message = match result {
Some(v) => match v {
Ok(_) => BluetoothObjectMsg::BluetoothWriteValue,
Err(e) => send_error!(sender, e.to_string()),
},
None => send_error!(sender, "No characteristic or descriptor found with that id"),
};
sender.send(message).unwrap();
}
}

View file

@ -13,6 +13,7 @@
extern crate brotli;
extern crate cookie as cookie_rs;
extern crate device;
extern crate devtools_traits;
extern crate flate2;
extern crate hyper;
@ -39,6 +40,7 @@ extern crate webrender_traits;
extern crate websocket;
pub mod about_loader;
pub mod bluetooth_thread;
pub mod chrome_loader;
pub mod cookie;
pub mod cookie_storage;

View file

@ -0,0 +1,69 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use ipc_channel::ipc::IpcSender;
#[derive(Deserialize, Serialize)]
pub enum BluetoothMethodMsg {
RequestDevice(IpcSender<BluetoothObjectMsg>),
GATTServerConnect(String, IpcSender<BluetoothObjectMsg>),
GATTServerDisconnect(String, IpcSender<BluetoothObjectMsg>),
GetPrimaryService(String, IpcSender<BluetoothObjectMsg>),
GetCharacteristic(String, IpcSender<BluetoothObjectMsg>),
GetDescriptor(String, IpcSender<BluetoothObjectMsg>),
ReadValue(String, IpcSender<BluetoothObjectMsg>),
WriteValue(String, Vec<u8>, IpcSender<BluetoothObjectMsg>),
Exit,
}
#[derive(Deserialize, Serialize)]
pub enum BluetoothObjectMsg {
BluetoothDevice {
// Bluetooth Device properties
id: String,
name: Option<String>,
device_class: Option<u32>,
vendor_id_source: Option<String>,
vendor_id: Option<u32>,
product_id: Option<u32>,
product_version: Option<u32>,
// Advertisiong Data properties
appearance: Option<u16>,
tx_power: Option<i8>,
rssi: Option<i8>
},
BluetoothServer {
connected: bool
},
BluetoothService {
uuid: String,
is_primary: bool,
instance_id: String
},
BluetoothCharacteristic {
// Characteristic
uuid: String,
instance_id: String,
// Characteristic properties
broadcast: bool,
read: bool,
write_without_response: bool,
write: bool,
notify: bool,
indicate: bool,
authenticated_signed_writes: bool,
reliable_write: bool,
writable_auxiliaries: bool
},
BluetoothDescriptor {
uuid: String,
instance_id: String
},
BluetoothReadValue {
value: Vec<u8>
},
BluetoothWriteValue,
Error {
error: String
},
}

View file

@ -40,6 +40,7 @@ use std::thread;
use url::Url;
use websocket::header;
pub mod bluetooth_thread;
pub mod hosts;
pub mod image_cache_thread;
pub mod net_error_list;

View file

@ -4,10 +4,15 @@
use dom::bindings::codegen::Bindings::BluetoothBinding;
use dom::bindings::codegen::Bindings::BluetoothBinding::BluetoothMethods;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::VendorIDSource;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bluetoothadvertisingdata::BluetoothAdvertisingData;
use dom::bluetoothdevice::BluetoothDevice;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::{BluetoothMethodMsg, BluetoothObjectMsg};
use util::str::DOMString;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetooth
#[dom_struct]
@ -27,13 +32,67 @@ impl Bluetooth {
global,
BluetoothBinding::Wrap)
}
fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
let global_root = self.global();
let global_ref = global_root.r();
global_ref.as_window().bluetooth_thread()
}
}
impl BluetoothMethods for Bluetooth {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
fn RequestDevice(&self) -> Option<Root<BluetoothDevice>> {
//UNIMPLEMENTED
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(BluetoothMethodMsg::RequestDevice(sender)).unwrap();
let device = receiver.recv().unwrap();
match device {
BluetoothObjectMsg::BluetoothDevice {
id,
name,
device_class,
vendor_id_source,
vendor_id,
product_id,
product_version,
appearance,
tx_power,
rssi,
} => {
let ad_data = &BluetoothAdvertisingData::new(self.global().r(),
appearance,
tx_power,
rssi);
let vendor_id_source = match vendor_id_source {
Some(vid) => match vid.as_ref() {
"bluetooth" => Some(VendorIDSource::Bluetooth),
"usb" => Some(VendorIDSource::Usb),
_ => Some(VendorIDSource::Unknown),
},
None => None,
};
let name = match name {
Some(n) => Some(DOMString::from(n)),
None => None,
};
Some(BluetoothDevice::new(self.global().r(),
DOMString::from(id),
name,
ad_data,
device_class,
vendor_id_source,
vendor_id,
product_id,
product_version))
},
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
None
},
_ => unreachable!()
}
}
}

View file

@ -2,16 +2,24 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding::
BluetoothRemoteGATTCharacteristicMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
use dom::bindings::error::Error::Network;
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::ByteString;
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::{BluetoothMethodMsg, BluetoothObjectMsg};
use util::str::DOMString;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattcharacteristic
@ -21,34 +29,49 @@ pub struct BluetoothRemoteGATTCharacteristic {
service: MutHeap<JS<BluetoothRemoteGATTService>>,
uuid: DOMString,
properties: MutHeap<JS<BluetoothCharacteristicProperties>>,
value: Option<ByteString>,
value: DOMRefCell<Option<ByteString>>,
instanceID: String,
}
impl BluetoothRemoteGATTCharacteristic {
pub fn new_inherited(service: &BluetoothRemoteGATTService,
uuid: DOMString,
properties: &BluetoothCharacteristicProperties)
properties: &BluetoothCharacteristicProperties,
instanceID: String)
-> BluetoothRemoteGATTCharacteristic {
BluetoothRemoteGATTCharacteristic {
reflector_: Reflector::new(),
service: MutHeap::new(service),
uuid: uuid,
properties: MutHeap::new(properties),
value: None,
value: DOMRefCell::new(None),
instanceID: instanceID,
}
}
pub fn new(global: GlobalRef,
service: &BluetoothRemoteGATTService,
uuid: DOMString,
properties: &BluetoothCharacteristicProperties)
properties: &BluetoothCharacteristicProperties,
instanceID: String)
-> Root<BluetoothRemoteGATTCharacteristic> {
reflect_dom_object(box BluetoothRemoteGATTCharacteristic::new_inherited(service,
uuid,
properties),
properties,
instanceID),
global,
BluetoothRemoteGATTCharacteristicBinding::Wrap)
}
fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
let global_root = self.global();
let global_ref = global_root.r();
global_ref.as_window().bluetooth_thread()
}
pub fn get_instance_id(&self) -> String {
self.instanceID.clone()
}
}
impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteristic {
@ -70,18 +93,78 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
fn GetDescriptor(&self) -> Option<Root<BluetoothRemoteGATTDescriptor>> {
//UNIMPLEMENTED
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::GetDescriptor(self.get_instance_id(), sender)).unwrap();
let descriptor = receiver.recv().unwrap();
match descriptor {
BluetoothObjectMsg::BluetoothDescriptor {
uuid,
instance_id
} => {
Some(BluetoothRemoteGATTDescriptor::new(self.global().r(),
&self,
DOMString::from(uuid),
instance_id))
},
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
None
},
_ => unreachable!()
}
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-value
fn GetValue(&self) -> Option<ByteString> {
self.value.clone()
self.value.borrow().clone()
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
fn ReadValue(&self) -> ByteString {
//UNIMPLEMENTED
ByteString::new(vec!())
fn ReadValue(&self) -> Fallible<ByteString> {
let (sender, receiver) = ipc::channel().unwrap();
if !self.Service().Device().Gatt().Connected() {
Err(Network)
}
else {
self.get_bluetooth_thread().send(
BluetoothMethodMsg::ReadValue(self.get_instance_id(), sender)).unwrap();
let result = receiver.recv().unwrap();
let value = match result {
BluetoothObjectMsg::BluetoothReadValue {
value
} => {
Some(ByteString::new(value))
},
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
None
},
_ => unreachable!()
};
*self.value.borrow_mut() = value;
Ok(self.GetValue().unwrap())
}
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
fn WriteValue(&self, value: Vec<u8>) {
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::WriteValue(self.get_instance_id(), value, sender)).unwrap();
let result = receiver.recv().unwrap();
match result {
BluetoothObjectMsg::BluetoothWriteValue => (),
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
},
_ => unreachable!()
};
}
}

View file

@ -2,13 +2,23 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding::
BluetoothRemoteGATTCharacteristicMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding::BluetoothRemoteGATTDescriptorMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
use dom::bindings::error::Error::Network;
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::ByteString;
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::{BluetoothMethodMsg, BluetoothObjectMsg};
use util::str::DOMString;
// http://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattdescriptor
@ -17,30 +27,45 @@ pub struct BluetoothRemoteGATTDescriptor {
reflector_: Reflector,
characteristic: MutHeap<JS<BluetoothRemoteGATTCharacteristic>>,
uuid: DOMString,
value: Option<ByteString>,
value: DOMRefCell<Option<ByteString>>,
instanceID: String,
}
impl BluetoothRemoteGATTDescriptor {
pub fn new_inherited(characteristic: &BluetoothRemoteGATTCharacteristic,
uuid: DOMString)
uuid: DOMString,
instanceID: String)
-> BluetoothRemoteGATTDescriptor {
BluetoothRemoteGATTDescriptor {
reflector_: Reflector::new(),
characteristic: MutHeap::new(characteristic),
uuid: uuid,
value: None,
value: DOMRefCell::new(None),
instanceID: instanceID,
}
}
pub fn new(global: GlobalRef,
characteristic: &BluetoothRemoteGATTCharacteristic,
uuid: DOMString)
uuid: DOMString,
instanceID: String)
-> Root<BluetoothRemoteGATTDescriptor>{
reflect_dom_object(box BluetoothRemoteGATTDescriptor::new_inherited(characteristic,
uuid),
uuid,
instanceID),
global,
BluetoothRemoteGATTDescriptorBinding::Wrap)
}
fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
let global_root = self.global();
let global_ref = global_root.r();
global_ref.as_window().bluetooth_thread()
}
pub fn get_instance_id(&self) -> String {
self.instanceID.clone()
}
}
impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
@ -57,12 +82,52 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-value
fn GetValue(&self) -> Option<ByteString> {
self.value.clone()
self.value.borrow().clone()
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue
fn ReadValue(&self) -> ByteString {
//UNIMPLEMENTED
ByteString::new(vec!())
fn ReadValue(&self) -> Fallible<ByteString> {
let (sender, receiver) = ipc::channel().unwrap();
if !self.Characteristic().Service().Device().Gatt().Connected() {
Err(Network)
}
else {
self.get_bluetooth_thread().send(
BluetoothMethodMsg::ReadValue(self.get_instance_id(), sender)).unwrap();
let result = receiver.recv().unwrap();
let value = match result {
BluetoothObjectMsg::BluetoothReadValue {
value
} => {
Some(ByteString::new(value))
},
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
None
},
_ => unreachable!()
};
*self.value.borrow_mut() = value;
Ok(self.GetValue().unwrap())
}
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue
fn WriteValue(&self, value: Vec<u8>) {
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::WriteValue(self.get_instance_id(), value, sender)).unwrap();
let result = receiver.recv().unwrap();
match result {
BluetoothObjectMsg::BluetoothWriteValue => (),
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
},
_ => unreachable!()
};
}
}

View file

@ -2,14 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::{BluetoothMethodMsg, BluetoothObjectMsg};
use std::cell::Cell;
use util::str::DOMString;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattserver
#[dom_struct]
@ -20,21 +24,25 @@ pub struct BluetoothRemoteGATTServer {
}
impl BluetoothRemoteGATTServer {
pub fn new_inherited(device: &BluetoothDevice, is_connected: bool) -> BluetoothRemoteGATTServer {
pub fn new_inherited(device: &BluetoothDevice) -> BluetoothRemoteGATTServer {
BluetoothRemoteGATTServer {
reflector_: Reflector::new(),
device: MutHeap::new(device),
connected: Cell::new(is_connected),
connected: Cell::new(false),
}
}
pub fn new(global: GlobalRef, device: &BluetoothDevice, connected: bool) -> Root<BluetoothRemoteGATTServer> {
reflect_dom_object(box BluetoothRemoteGATTServer::new_inherited(
device,
connected),
pub fn new(global: GlobalRef, device: &BluetoothDevice) -> Root<BluetoothRemoteGATTServer> {
reflect_dom_object(box BluetoothRemoteGATTServer::new_inherited(device),
global,
BluetoothRemoteGATTServerBinding::Wrap)
}
fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
let global_root = self.global();
let global_ref = global_root.r();
global_ref.as_window().bluetooth_thread()
}
}
impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
@ -51,20 +59,72 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect
fn Connect(&self) -> Root<BluetoothRemoteGATTServer> {
if !self.connected.get() {
self.connected.set(true);
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::GATTServerConnect(String::from(self.Device().Id()), sender)).unwrap();
let server = receiver.recv().unwrap();
match server {
BluetoothObjectMsg::BluetoothServer {
connected
} => {
self.connected.set(connected);
},
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
},
_ => unreachable!()
}
Root::from_ref(self)
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-disconnect
fn Disconnect(&self) {
self.connected.set(false);
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::GATTServerDisconnect(String::from(self.Device().Id()), sender)).unwrap();
let server = receiver.recv().unwrap();
match server {
BluetoothObjectMsg::BluetoothServer {
connected
} => {
self.connected.set(connected);
},
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
},
_ => unreachable!()
}
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice
fn GetPrimaryService(&self) -> Option<Root<BluetoothRemoteGATTService>> {
//UNIMPLEMENTED
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::GetPrimaryService(String::from(self.Device().Id()), sender)).unwrap();
let service = receiver.recv().unwrap();
match service {
BluetoothObjectMsg::BluetoothService {
uuid,
is_primary,
instance_id
} => {
Some(BluetoothRemoteGATTService::new(self.global().r(),
&self.device.get(),
DOMString::from(uuid),
is_primary,
instance_id))
},
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
None
},
_ => unreachable!()
}
}
}

View file

@ -6,9 +6,12 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::{BluetoothMethodMsg, BluetoothObjectMsg};
use util::str::DOMString;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice
@ -18,32 +21,47 @@ pub struct BluetoothRemoteGATTService {
device: MutHeap<JS<BluetoothDevice>>,
uuid: DOMString,
isPrimary: bool,
instanceID: String,
}
impl BluetoothRemoteGATTService {
pub fn new_inherited(device: &BluetoothDevice,
uuid: DOMString,
isPrimary: bool)
isPrimary: bool,
instanceID: String)
-> BluetoothRemoteGATTService {
BluetoothRemoteGATTService {
reflector_: Reflector::new(),
device: MutHeap::new(device),
uuid: uuid,
isPrimary: isPrimary,
instanceID: instanceID,
}
}
pub fn new(global: GlobalRef,
device: &BluetoothDevice,
uuid: DOMString,
isPrimary: bool)
isPrimary: bool,
instanceID: String)
-> Root<BluetoothRemoteGATTService> {
reflect_dom_object(box BluetoothRemoteGATTService::new_inherited(device,
uuid,
isPrimary),
isPrimary,
instanceID),
global,
BluetoothRemoteGATTServiceBinding::Wrap)
}
fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
let global_root = self.global();
let global_ref = global_root.r();
global_ref.as_window().bluetooth_thread()
}
pub fn get_instance_id(&self) -> String {
self.instanceID.clone()
}
}
impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
@ -64,7 +82,47 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic
fn GetCharacteristic(&self) -> Option<Root<BluetoothRemoteGATTCharacteristic>> {
// UNIMPLEMENTED
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::GetCharacteristic(self.get_instance_id(), sender)).unwrap();
let characteristic = receiver.recv().unwrap();
match characteristic {
BluetoothObjectMsg::BluetoothCharacteristic {
uuid,
instance_id,
broadcast,
read,
write_without_response,
write,
notify,
indicate,
authenticated_signed_writes,
reliable_write,
writable_auxiliaries,
} => {
let properties = &BluetoothCharacteristicProperties::new(self.global().r(),
broadcast,
read,
write_without_response,
write,
notify,
indicate,
authenticated_signed_writes,
reliable_write,
writable_auxiliaries);
Some(BluetoothRemoteGATTCharacteristic::new(self.global().r(),
&self,
DOMString::from(uuid),
properties,
instance_id))
},
BluetoothObjectMsg::Error {
error
} => {
println!("{}", error);
None
},
_ => unreachable!()
}
}
}

View file

@ -7,7 +7,8 @@
// Allocation authorities for Vendor IDs:
enum VendorIDSource {
"bluetooth",
"usb"
"usb",
"unknown"
};
[Pref="dom.bluetooth.enabled"]

View file

@ -14,8 +14,10 @@ interface BluetoothRemoteGATTCharacteristic {
//Promise<BluetoothRemoteGATTDescriptor> getDescriptor(BluetoothDescriptorUUID descriptor);
//Promise<sequence<BluetoothRemoteGATTDescriptor>>
//getDescriptors(optional BluetoothDescriptorUUID descriptor);
//Promise<DataView> readValue();
[Throws]
ByteString readValue();
//Promise<DataView> readValue();
void writeValue(sequence<octet> value);
//Promise<void> writeValue(BufferSource value);
//Promise<void> startNotifications();
//Promise<void> stopNotifications();

View file

@ -9,8 +9,9 @@ interface BluetoothRemoteGATTDescriptor {
readonly attribute BluetoothRemoteGATTCharacteristic characteristic;
readonly attribute DOMString uuid;
readonly attribute ByteString? value;
[Throws]
ByteString readValue();
//Promise<DataView> readValue();
void writeValue(sequence<octet> value);
//Promise<void> writeValue(BufferSource value);
};

View file

@ -47,6 +47,7 @@ use msg::constellation_msg::{ConstellationChan, LoadData, PipelineId, SubpageId}
use msg::constellation_msg::{WindowSizeData, WindowSizeType};
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use net_traits::ResourceThread;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
use net_traits::storage_thread::{StorageThread, StorageType};
use num_traits::ToPrimitive;
@ -212,6 +213,10 @@ pub struct Window {
#[ignore_heap_size_of = "channels are hard"]
resource_thread: Arc<ResourceThread>,
/// A handle for communicating messages to the bluetooth thread.
#[ignore_heap_size_of = "channels are hard"]
bluetooth_thread: IpcSender<BluetoothMethodMsg>,
/// A handle for communicating messages to the storage thread.
#[ignore_heap_size_of = "channels are hard"]
storage_thread: StorageThread,
@ -334,6 +339,10 @@ impl Window {
&*self.page
}
pub fn bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
self.bluetooth_thread.clone()
}
pub fn storage_thread(&self) -> StorageThread {
self.storage_thread.clone()
}
@ -1401,6 +1410,7 @@ impl Window {
compositor: IpcSender<ScriptToCompositorMsg>,
image_cache_thread: ImageCacheThread,
resource_thread: Arc<ResourceThread>,
bluetooth_thread: IpcSender<BluetoothMethodMsg>,
storage_thread: StorageThread,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
@ -1456,6 +1466,7 @@ impl Window {
dom_static: GlobalStaticData::new(),
js_runtime: DOMRefCell::new(Some(runtime.clone())),
resource_thread: resource_thread,
bluetooth_thread: bluetooth_thread,
storage_thread: storage_thread,
constellation_chan: constellation_chan,
page_clip_rect: Cell::new(MAX_RECT),

View file

@ -64,6 +64,7 @@ use msg::constellation_msg::{PipelineId, PipelineNamespace};
use msg::constellation_msg::{SubpageId, WindowSizeData, WindowSizeType};
use msg::webdriver_msg::WebDriverScriptCommand;
use net_traits::LoadData as NetLoadData;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
use net_traits::storage_thread::StorageThread;
use net_traits::{AsyncResponseTarget, ControlMsg, LoadConsumer, LoadContext, Metadata, ResourceThread};
@ -310,6 +311,8 @@ pub struct ScriptThread {
/// A handle to the resource thread. This is an `Arc` to avoid running out of file descriptors if
/// there are many iframes.
resource_thread: Arc<ResourceThread>,
/// A handle to the bluetooth thread.
bluetooth_thread: IpcSender<BluetoothMethodMsg>,
/// A handle to the storage thread.
storage_thread: StorageThread,
@ -540,6 +543,7 @@ impl ScriptThread {
image_cache_port: image_cache_port,
resource_thread: Arc::new(state.resource_thread),
bluetooth_thread: state.bluetooth_thread,
storage_thread: state.storage_thread,
port: port,
@ -1482,6 +1486,7 @@ impl ScriptThread {
self.compositor.borrow_mut().clone(),
self.image_cache_thread.clone(),
self.resource_thread.clone(),
self.bluetooth_thread.clone(),
self.storage_thread.clone(),
self.mem_profiler_chan.clone(),
self.devtools_chan.clone(),

View file

@ -46,6 +46,7 @@ use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
use msg::constellation_msg::{PipelineNamespaceId, SubpageId};
use msg::webdriver_msg::WebDriverScriptCommand;
use net_traits::ResourceThread;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::ImageCacheThread;
use net_traits::response::HttpsState;
use net_traits::storage_thread::StorageThread;
@ -320,6 +321,8 @@ pub struct InitialScriptState {
pub scheduler_chan: IpcSender<TimerEventRequest>,
/// A channel to the resource manager thread.
pub resource_thread: ResourceThread,
/// A channel to the bluetooth thread.
pub bluetooth_thread: IpcSender<BluetoothMethodMsg>,
/// A channel to the storage thread.
pub storage_thread: StorageThread,
/// A channel to the image cache thread.

View file

@ -167,6 +167,15 @@ name = "block"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blurz"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dbus 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "brotli"
version = "0.3.20"
@ -414,6 +423,15 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dbus"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "debug_unreachable"
version = "0.1.1"
@ -430,6 +448,14 @@ dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "device"
version = "0.0.1"
source = "git+https://github.com/dati91/devices?branch=device-api#dccc5111e46124cef596cef10ce9056362892e59"
dependencies = [
"blurz 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "devtools"
version = "0.0.1"
@ -1307,6 +1333,7 @@ version = "0.0.1"
dependencies = [
"brotli 0.3.20 (git+https://github.com/ende76/brotli-rs)",
"cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"device 0.0.1 (git+https://github.com/dati91/devices?branch=device-api)",
"devtools_traits 0.0.1",
"flate2 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -71,9 +71,11 @@ use compositing::{CompositorProxy, CompositorThread, Constellation};
use gaol::sandbox::{ChildSandbox, ChildSandboxMethods};
use gfx::font_cache_thread::FontCacheThread;
use ipc_channel::ipc::{self, IpcSender};
use net::bluetooth_thread::BluetoothThreadFactory;
use net::image_cache_thread::new_image_cache_thread;
use net::resource_thread::new_resource_thread;
use net::storage_thread::StorageThreadFactory;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::storage_thread::StorageThread;
use profile::mem as profile_mem;
use profile::time as profile_time;
@ -208,6 +210,7 @@ fn create_constellation(opts: opts::Opts,
devtools_chan: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
supports_clipboard: bool,
webrender_api_sender: Option<webrender_traits::RenderApiSender>) -> Sender<ConstellationMsg> {
let bluetooth_thread: IpcSender<BluetoothMethodMsg> = BluetoothThreadFactory::new();
let resource_thread = new_resource_thread(opts.user_agent.clone(), devtools_chan.clone());
let image_cache_thread = new_image_cache_thread(resource_thread.clone(),
webrender_api_sender.as_ref().map(|wr| wr.create_api()));
@ -218,6 +221,7 @@ fn create_constellation(opts: opts::Opts,
let initial_state = InitialConstellationState {
compositor_proxy: compositor_proxy,
devtools_chan: devtools_chan,
bluetooth_thread: bluetooth_thread,
image_cache_thread: image_cache_thread,
font_cache_thread: font_cache_thread,
resource_thread: resource_thread,