aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock3
-rw-r--r--components/bluetooth/Cargo.toml5
-rw-r--r--components/bluetooth/lib.rs54
-rw-r--r--components/compositing/compositor_thread.rs3
-rw-r--r--components/servo/lib.rs2
-rw-r--r--ports/servo/browser.rs39
6 files changed, 68 insertions, 38 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 69c7b234e16..63da933466e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -179,11 +179,12 @@ version = "0.0.1"
dependencies = [
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bluetooth_traits 0.0.1",
+ "compositing 0.0.1",
"device 0.0.1 (git+https://github.com/servo/devices)",
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_config 0.0.1",
"servo_rand 0.0.1",
- "tinyfiledialogs 3.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
diff --git a/components/bluetooth/Cargo.toml b/components/bluetooth/Cargo.toml
index 53784d13e9c..bc172342977 100644
--- a/components/bluetooth/Cargo.toml
+++ b/components/bluetooth/Cargo.toml
@@ -12,11 +12,10 @@ path = "lib.rs"
[dependencies]
bitflags = "1.0"
bluetooth_traits = {path = "../bluetooth_traits"}
+compositing = {path = "../compositing"}
device = {git = "https://github.com/servo/devices", features = ["bluetooth-test"]}
ipc-channel = "0.10"
+log = "0.4"
servo_config = {path = "../config"}
servo_rand = {path = "../rand"}
uuid = {version = "0.6", features = ["v4"]}
-
-[target.'cfg(target_os = "linux")'.dependencies]
-tinyfiledialogs = "3.0"
diff --git a/components/bluetooth/lib.rs b/components/bluetooth/lib.rs
index a68b701d883..3df295b56e9 100644
--- a/components/bluetooth/lib.rs
+++ b/components/bluetooth/lib.rs
@@ -5,12 +5,13 @@
#[macro_use]
extern crate bitflags;
extern crate bluetooth_traits;
+extern crate compositing;
extern crate device;
extern crate ipc_channel;
+#[macro_use]
+extern crate log;
extern crate servo_config;
extern crate servo_rand;
-#[cfg(target_os = "linux")]
-extern crate tinyfiledialogs;
extern crate uuid;
pub mod test;
@@ -20,10 +21,10 @@ use bluetooth_traits::{BluetoothDeviceMsg, BluetoothRequest, BluetoothResponse,
use bluetooth_traits::{BluetoothError, BluetoothResponseResult, BluetoothResult};
use bluetooth_traits::blocklist::{uuid_is_blocklisted, Blocklist};
use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence, RequestDeviceoptions};
+use compositing::compositor_thread::{EmbedderMsg, EmbedderProxy};
use device::bluetooth::{BluetoothAdapter, BluetoothDevice, BluetoothGATTCharacteristic};
use device::bluetooth::{BluetoothGATTDescriptor, BluetoothGATTService};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
-#[cfg(target_os = "linux")]
use servo_config::opts;
use servo_config::prefs::PREFS;
use servo_rand::Rng;
@@ -39,12 +40,6 @@ const MAXIMUM_TRANSACTION_TIME: u8 = 30;
const CONNECTION_TIMEOUT_MS: u64 = 1000;
// The discovery session needs some time to find any nearby devices
const DISCOVERY_TIMEOUT_MS: u64 = 1500;
-#[cfg(target_os = "linux")]
-const DIALOG_TITLE: &'static str = "Choose a device";
-#[cfg(target_os = "linux")]
-const DIALOG_COLUMN_ID: &'static str = "Id";
-#[cfg(target_os = "linux")]
-const DIALOG_COLUMN_NAME: &'static str = "Name";
bitflags! {
struct Flags: u32 {
@@ -69,11 +64,11 @@ macro_rules! return_if_cached(
);
pub trait BluetoothThreadFactory {
- fn new() -> Self;
+ fn new(embedder_proxy: EmbedderProxy) -> Self;
}
impl BluetoothThreadFactory for IpcSender<BluetoothRequest> {
- fn new() -> IpcSender<BluetoothRequest> {
+ fn new(embedder_proxy: EmbedderProxy) -> IpcSender<BluetoothRequest> {
let (sender, receiver) = ipc::channel().unwrap();
let adapter = if Some(true) == PREFS.get("dom.bluetooth.enabled").as_boolean() {
BluetoothAdapter::init()
@@ -81,7 +76,7 @@ impl BluetoothThreadFactory for IpcSender<BluetoothRequest> {
BluetoothAdapter::init_mock()
}.ok();
thread::Builder::new().name("BluetoothThread".to_owned()).spawn(move || {
- BluetoothManager::new(receiver, adapter).start();
+ BluetoothManager::new(receiver, adapter, embedder_proxy).start();
}).expect("Thread spawning failed");
sender
}
@@ -206,10 +201,13 @@ pub struct BluetoothManager {
cached_characteristics: HashMap<String, BluetoothGATTCharacteristic>,
cached_descriptors: HashMap<String, BluetoothGATTDescriptor>,
allowed_services: HashMap<String, HashSet<String>>,
+ embedder_proxy: EmbedderProxy,
}
impl BluetoothManager {
- pub fn new(receiver: IpcReceiver<BluetoothRequest>, adapter: Option<BluetoothAdapter>) -> BluetoothManager {
+ pub fn new(receiver: IpcReceiver<BluetoothRequest>,
+ adapter: Option<BluetoothAdapter>,
+ embedder_proxy: EmbedderProxy) -> BluetoothManager {
BluetoothManager {
receiver: receiver,
adapter: adapter,
@@ -222,6 +220,7 @@ impl BluetoothManager {
cached_characteristics: HashMap::new(),
cached_descriptors: HashMap::new(),
allowed_services: HashMap::new(),
+ embedder_proxy: embedder_proxy,
}
}
@@ -366,10 +365,9 @@ impl BluetoothManager {
None
}
- #[cfg(target_os = "linux")]
fn select_device(&mut self, devices: Vec<BluetoothDevice>, adapter: &BluetoothAdapter) -> Option<String> {
if is_mock_adapter(adapter) || opts::get().headless {
- for device in devices {
+ for device in &devices {
if let Ok(address) = device.get_address() {
return Some(address);
}
@@ -382,28 +380,18 @@ impl BluetoothManager {
dialog_rows.extend_from_slice(&[device.get_address().unwrap_or("".to_string()),
device.get_name().unwrap_or("".to_string())]);
}
- let dialog_rows: Vec<&str> = dialog_rows.iter()
- .map(|s| s.as_ref())
- .collect();
- let dialog_rows: &[&str] = dialog_rows.as_slice();
- if let Some(device) = tinyfiledialogs::list_dialog(DIALOG_TITLE,
- &[DIALOG_COLUMN_ID, DIALOG_COLUMN_NAME],
- Some(dialog_rows)) {
- // The device string format will be "Address|Name". We need the first part of it.
- return device.split("|").next().map(|s| s.to_string());
- }
- None
- }
+ let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!");
+ let msg = EmbedderMsg::GetSelectedBluetoothDevice(dialog_rows, ipc_sender);
+ self.embedder_proxy.send(msg);
- #[cfg(not(target_os = "linux"))]
- fn select_device(&mut self, devices: Vec<BluetoothDevice>, _adapter: &BluetoothAdapter) -> Option<String> {
- for device in devices {
- if let Ok(address) = device.get_address() {
- return Some(address);
+ match ipc_receiver.recv() {
+ Ok(result) => result,
+ Err(e) => {
+ warn!("Failed to receive files from embedder ({}).", e);
+ None
}
}
- None
}
fn generate_device_id(&mut self) -> String {
diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs
index 3f43c2ba2bb..3d9a320c897 100644
--- a/components/compositing/compositor_thread.rs
+++ b/components/compositing/compositor_thread.rs
@@ -141,6 +141,8 @@ pub enum EmbedderMsg {
LoadComplete(TopLevelBrowsingContextId),
/// A pipeline panicked. First string is the reason, second one is the backtrace.
Panic(TopLevelBrowsingContextId, String, Option<String>),
+ /// Open dialog to select bluetooth device.
+ GetSelectedBluetoothDevice(Vec<String>, IpcSender<Option<String>>),
/// Servo has shut down
Shutdown,
}
@@ -241,6 +243,7 @@ impl Debug for EmbedderMsg {
EmbedderMsg::LoadStart(..) => write!(f, "LoadStart"),
EmbedderMsg::LoadComplete(..) => write!(f, "LoadComplete"),
EmbedderMsg::Panic(..) => write!(f, "Panic"),
+ EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"),
EmbedderMsg::Shutdown => write!(f, "Shutdown"),
}
}
diff --git a/components/servo/lib.rs b/components/servo/lib.rs
index 1d8e64ab8e4..3b7973ba203 100644
--- a/components/servo/lib.rs
+++ b/components/servo/lib.rs
@@ -458,7 +458,7 @@ fn create_constellation(user_agent: Cow<'static, str>,
webrender_api_sender: webrender_api::RenderApiSender,
window_gl: Rc<gl::Gl>)
-> (Sender<ConstellationMsg>, SWManagerSenders) {
- let bluetooth_thread: IpcSender<BluetoothRequest> = BluetoothThreadFactory::new();
+ let bluetooth_thread: IpcSender<BluetoothRequest> = BluetoothThreadFactory::new(embedder_proxy.clone());
let (public_resource_threads, private_resource_threads) =
new_resource_threads(user_agent,
diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs
index ff0a8d20cee..92422388e22 100644
--- a/ports/servo/browser.rs
+++ b/ports/servo/browser.rs
@@ -7,6 +7,7 @@ use glutin_app::keyutils::{CMD_OR_CONTROL, CMD_OR_ALT};
use glutin_app::window::{Window, LINE_HEIGHT};
use servo::compositing::compositor_thread::EmbedderMsg;
use servo::compositing::windowing::{WebRenderDebugOption, WindowEvent};
+use servo::ipc_channel::ipc::IpcSender;
use servo::msg::constellation_msg::{Key, TopLevelBrowsingContextId as BrowserId};
use servo::msg::constellation_msg::{KeyModifiers, KeyState, TraversalDirection};
use servo::net_traits::pub_domains::is_reg_domain;
@@ -16,6 +17,8 @@ use servo::servo_url::ServoUrl;
use servo::webrender_api::ScrollLocation;
use std::mem;
use std::rc::Rc;
+#[cfg(target_os = "linux")]
+use std::thread;
use tinyfiledialogs;
pub struct Browser {
@@ -288,6 +291,9 @@ impl Browser {
self.shutdown_requested = true;
},
EmbedderMsg::Panic(_browser_id, _reason, _backtrace) => {
+ },
+ EmbedderMsg::GetSelectedBluetoothDevice(devices, sender) => {
+ platform_get_selected_devices(devices, sender);
}
}
}
@@ -295,6 +301,39 @@ impl Browser {
}
+#[cfg(target_os = "linux")]
+fn platform_get_selected_devices(devices: Vec<String>, sender: IpcSender<Option<String>>) {
+ let picker_name = "Choose a device";
+
+ thread::Builder::new().name(picker_name.to_owned()).spawn(move || {
+ let dialog_rows: Vec<&str> = devices.iter()
+ .map(|s| s.as_ref())
+ .collect();
+ let dialog_rows: Option<&[&str]> = Some(dialog_rows.as_slice());
+
+ match tinyfiledialogs::list_dialog("Choose a device", &["Id", "Name"], dialog_rows) {
+ Some(device) => {
+ // The device string format will be "Address|Name". We need the first part of it.
+ let address = device.split("|").next().map(|s| s.to_string());
+ let _ = sender.send(address);
+ },
+ None => {
+ let _ = sender.send(None);
+ }
+ }
+ }).expect("Thread spawning failed");
+}
+
+#[cfg(not(target_os = "linux"))]
+fn platform_get_selected_devices(devices: Vec<String>, sender: IpcSender<Option<String>>) {
+ for device in devices {
+ if let Some(address) = device.split("|").next().map(|s| s.to_string()) {
+ let _ = sender.send(Some(address));
+ }
+ }
+ let _ = sender.send(None);
+}
+
fn sanitize_url(request: &str) -> Option<ServoUrl> {
let request = request.trim();
ServoUrl::parse(&request).ok()