From 1c465bcd668426207e41b77329afadd069a79d82 Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Fri, 30 Mar 2018 10:33:19 -0700 Subject: [PATCH 01/11] refactor(resourcethread): expose constellationmsg channel --- Cargo.lock | 1 + components/net/Cargo.toml | 1 + components/net/lib.rs | 1 + components/net/resource_thread.rs | 21 +++++++++++++-------- components/servo/lib.rs | 4 +++- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6002808308..d2c1c8c77bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1910,6 +1910,7 @@ dependencies = [ "net_traits 0.0.1", "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", "profile_traits 0.0.1", + "script_traits 0.0.1", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "servo-websocket 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml index 4fdee627ca9..5e747577ada 100644 --- a/components/net/Cargo.toml +++ b/components/net/Cargo.toml @@ -34,6 +34,7 @@ msg = {path = "../msg"} net_traits = {path = "../net_traits"} openssl = "0.9" profile_traits = {path = "../profile_traits"} +script_traits = {path = "../script_traits"} serde = "1.0" serde_json = "1.0" servo_allocator = {path = "../allocator"} diff --git a/components/net/lib.rs b/components/net/lib.rs index 1bc43b361f4..1e17fd0988d 100644 --- a/components/net/lib.rs +++ b/components/net/lib.rs @@ -29,6 +29,7 @@ extern crate net_traits; extern crate openssl; #[macro_use] extern crate profile_traits; +extern crate script_traits; #[macro_use] extern crate serde; extern crate serde_json; extern crate servo_allocator; diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index 5e708465bf7..a7715e1fdf7 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -28,6 +28,7 @@ use net_traits::storage_thread::StorageThreadMsg; use profile_traits::mem::{Report, ReportsChan, ReportKind}; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan; +use script_traits::ConstellationMsg; use serde::{Deserialize, Serialize}; use serde_json; use servo_allocator; @@ -41,7 +42,7 @@ use std::io::prelude::*; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex, RwLock}; -use std::sync::mpsc::Sender; +use std::sync::mpsc::{self, Sender}; use std::thread; use storage_thread::StorageThreadFactory; use websocket_loader; @@ -54,8 +55,8 @@ pub fn new_resource_threads(user_agent: Cow<'static, str>, time_profiler_chan: ProfilerChan, mem_profiler_chan: MemProfilerChan, config_dir: Option) - -> (ResourceThreads, ResourceThreads) { - let (public_core, private_core) = new_core_resource_thread( + -> (ResourceThreads, ResourceThreads, Sender>) { + let (public_core, private_core, constellation_sender) = new_core_resource_thread( user_agent, devtools_chan, time_profiler_chan, @@ -63,7 +64,8 @@ pub fn new_resource_threads(user_agent: Cow<'static, str>, config_dir.clone()); let storage: IpcSender = StorageThreadFactory::new(config_dir); (ResourceThreads::new(public_core, storage.clone()), - ResourceThreads::new(private_core, storage)) + ResourceThreads::new(private_core, storage), + constellation_sender) } @@ -73,14 +75,16 @@ pub fn new_core_resource_thread(user_agent: Cow<'static, str>, time_profiler_chan: ProfilerChan, mem_profiler_chan: MemProfilerChan, config_dir: Option) - -> (CoreResourceThread, CoreResourceThread) { + -> (CoreResourceThread, CoreResourceThread, Sender>) { let (public_setup_chan, public_setup_port) = ipc::channel().unwrap(); let (private_setup_chan, private_setup_port) = ipc::channel().unwrap(); let (report_chan, report_port) = ipc::channel().unwrap(); + let (constellation_sender, constellation_receiver) = mpsc::channel(); thread::Builder::new().name("ResourceManager".to_owned()).spawn(move || { + let constellation_chan = constellation_receiver.recv().unwrap(); let resource_manager = CoreResourceManager::new( - user_agent, devtools_chan, time_profiler_chan + user_agent, devtools_chan, time_profiler_chan, constellation_chan ); let mut channel_manager = ResourceChannelManager { @@ -99,7 +103,7 @@ pub fn new_core_resource_thread(user_agent: Cow<'static, str>, |report_chan| report_chan); }).expect("Thread spawning failed"); - (public_setup_chan, private_setup_chan) + (public_setup_chan, private_setup_chan, constellation_sender) } struct ResourceChannelManager { @@ -374,7 +378,8 @@ pub struct CoreResourceManager { impl CoreResourceManager { pub fn new(user_agent: Cow<'static, str>, devtools_channel: Option>, - _profiler_chan: ProfilerChan) -> CoreResourceManager { + _profiler_chan: ProfilerChan, + constellation_chan: Sender) -> CoreResourceManager { CoreResourceManager { user_agent: user_agent, devtools_chan: devtools_channel, diff --git a/components/servo/lib.rs b/components/servo/lib.rs index e0e8f41b1b3..4fd94207b47 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -457,7 +457,7 @@ fn create_constellation(user_agent: Cow<'static, str>, -> (Sender, SWManagerSenders) { let bluetooth_thread: IpcSender = BluetoothThreadFactory::new(embedder_proxy.clone()); - let (public_resource_threads, private_resource_threads) = + let (public_resource_threads, private_resource_threads, resource_constellation_sender) = new_resource_threads(user_agent, devtools_chan.clone(), time_profiler_chan.clone(), @@ -533,6 +533,8 @@ fn create_constellation(user_agent: Cow<'static, str>, webvr_constellation_sender.send(constellation_chan.clone()).unwrap(); } + resource_constellation_sender.send(constellation_chan.clone()).unwrap(); + // channels to communicate with Service Worker Manager let sw_senders = SWManagerSenders { swmanager_sender: from_swmanager_sender, From b396a2f6cab1690de3f9c605aa12130852e8cd46 Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Fri, 30 Mar 2018 10:49:24 -0700 Subject: [PATCH 02/11] refactor(filemanager): send constellationmsg to select file --- components/constellation/constellation.rs | 3 ++ components/net/filemanager_thread.rs | 66 +++++++++++++---------- components/net/resource_thread.rs | 4 +- components/script_traits/lib.rs | 3 ++ 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 93581d9f884..1a8d8e825e0 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -1012,6 +1012,9 @@ impl Constellation FromCompositorMsg::SetCursor(cursor) => { self.handle_set_cursor_msg(cursor) } + FromCompositorMsg::OpenFileSelectDialog(patterns, multiple_files, sender) => { + return; + } } } diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index 4a84cd29714..bc433895ba9 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -2,11 +2,12 @@ * 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; +use ipc_channel::ipc::{self, IpcSender}; use mime_guess::guess_mime_type_opt; use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError}; use net_traits::filemanager_thread::{FileManagerResult, FileManagerThreadMsg, FileOrigin, FilterPattern}; use net_traits::filemanager_thread::{FileManagerThreadError, ReadFileProgress, RelativePos, SelectedFile}; +use script_traits::ConstellationMsg; #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use servo_config::opts; use servo_config::prefs::PREFS; @@ -17,6 +18,7 @@ use std::ops::Index; use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering}; +use std::sync::mpsc::Sender; use std::thread; #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use tinyfiledialogs; @@ -123,12 +125,14 @@ enum FileImpl { #[derive(Clone)] pub struct FileManager { + constellation_chan: Sender, store: Arc, } impl FileManager { - pub fn new() -> FileManager { + pub fn new(constellation_chan: Sender) -> FileManager { FileManager { + constellation_chan: constellation_chan, store: Arc::new(FileManagerStore::new()), } } @@ -159,22 +163,20 @@ impl FileManager { } /// Message handler - pub fn handle(&self, - msg: FileManagerThreadMsg, - ui: &'static UI) - where UI: UIProvider + 'static, - { + pub fn handle(&self, msg: FileManagerThreadMsg) { match msg { FileManagerThreadMsg::SelectFile(filter, sender, origin, opt_test_path) => { let store = self.store.clone(); + let constellation_chan = self.constellation_chan.clone(); thread::Builder::new().name("select file".to_owned()).spawn(move || { - store.select_file(filter, sender, origin, opt_test_path, ui); + store.select_file(filter, sender, origin, opt_test_path, constellation_chan); }).expect("Thread spawning failed"); } FileManagerThreadMsg::SelectFiles(filter, sender, origin, opt_test_paths) => { let store = self.store.clone(); + let constellation_chan = self.constellation_chan.clone(); thread::Builder::new().name("select files".to_owned()).spawn(move || { - store.select_files(filter, sender, origin, opt_test_paths, ui); + store.select_files(filter, sender, origin, opt_test_paths, constellation_chan); }).expect("Thread spawning failed"); } FileManagerThreadMsg::ReadFile(sender, id, check_url_validity, origin) => { @@ -279,21 +281,33 @@ impl FileManagerStore { } } - fn select_file(&self, - patterns: Vec, - sender: IpcSender>, - origin: FileOrigin, - opt_test_path: Option, - ui: &UI) - where UI: UIProvider, - { + fn get_selected_files(&self, + patterns: Vec, + multiple_files: bool, + constellation_chan: Sender) -> Option> { + if opts::get().headless { + return None; + } + + let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); + let msg = ConstellationMsg::OpenFileSelectDialog(patterns, multiple_files, ipc_sender); + + constellation_chan.send(msg).map(|_| ipc_receiver.recv().unwrap()).unwrap_or_default() + } + + fn select_file(&self, + patterns: Vec, + sender: IpcSender>, + origin: FileOrigin, + opt_test_path: Option, + constellation_chan: Sender) { // Check if the select_files preference is enabled // to ensure process-level security against compromised script; // Then try applying opt_test_path directly for testing convenience let opt_s = if select_files_pref_enabled() { opt_test_path } else { - ui.open_file_dialog("", patterns) + self.get_selected_files(patterns, false, constellation_chan).map(|mut x| x.pop().unwrap()) }; match opt_s { @@ -309,21 +323,19 @@ impl FileManagerStore { } } - fn select_files(&self, - patterns: Vec, - sender: IpcSender>>, - origin: FileOrigin, - opt_test_paths: Option>, - ui: &UI) - where UI: UIProvider, - { + fn select_files(&self, + patterns: Vec, + sender: IpcSender>>, + origin: FileOrigin, + opt_test_paths: Option>, + constellation_chan: Sender) { // Check if the select_files preference is enabled // to ensure process-level security against compromised script; // Then try applying opt_test_paths directly for testing convenience let opt_v = if select_files_pref_enabled() { opt_test_paths } else { - ui.open_file_dialog_multi("", patterns) + self.get_selected_files(patterns, true, constellation_chan) }; match opt_v { diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index a7715e1fdf7..fce89fd6624 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -267,7 +267,7 @@ impl ResourceChannelManager { CoreResourceMsg::Synchronize(sender) => { let _ = sender.send(()); } - CoreResourceMsg::ToFileManager(msg) => self.resource_manager.filemanager.handle(msg, TFD_PROVIDER), + CoreResourceMsg::ToFileManager(msg) => self.resource_manager.filemanager.handle(msg), CoreResourceMsg::Exit(sender) => { if let Some(ref config_dir) = self.config_dir { match http_state.auth_cache.read() { @@ -384,7 +384,7 @@ impl CoreResourceManager { user_agent: user_agent, devtools_chan: devtools_channel, swmanager_chan: None, - filemanager: FileManager::new(), + filemanager: FileManager::new(constellation_chan), } } diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 272cfe3cedb..584798caf0e 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -51,6 +51,7 @@ use libc::c_void; use msg::constellation_msg::{BrowsingContextId, HistoryStateId, Key, KeyModifiers, KeyState, PipelineId}; use msg::constellation_msg::{PipelineNamespaceId, TraversalDirection, TopLevelBrowsingContextId}; use net_traits::{FetchResponseMsg, ReferrerPolicy, ResourceThreads}; +use net_traits::filemanager_thread::FilterPattern; use net_traits::image::base::Image; use net_traits::image::base::PixelFormat; use net_traits::image_cache::ImageCache; @@ -705,6 +706,8 @@ pub enum ConstellationMsg { ForwardEvent(PipelineId, CompositorEvent), /// Requesting a change to the onscreen cursor. SetCursor(CursorKind), + /// Requesting to open file select dialog + OpenFileSelectDialog(Vec, bool, IpcSender>>), } /// Resources required by workerglobalscopes From 2071245e5f59d1864e1463e022789c6f3cb37ca5 Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Fri, 30 Mar 2018 12:01:48 -0700 Subject: [PATCH 03/11] refactor(compositor): expose new embeddermsg --- components/compositing/compositor_thread.rs | 4 ++++ components/constellation/constellation.rs | 11 ++++++++++- ports/servo/browser.rs | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index 0b042ec5350..f4aa96c20b9 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -9,6 +9,7 @@ use compositor::CompositingReason; use gfx_traits::Epoch; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState, PipelineId, TopLevelBrowsingContextId}; +use net_traits::filemanager_thread::FilterPattern; use net_traits::image::base::Image; use profile_traits::mem; use profile_traits::time; @@ -143,6 +144,8 @@ pub enum EmbedderMsg { Panic(TopLevelBrowsingContextId, String, Option), /// Open dialog to select bluetooth device. GetSelectedBluetoothDevice(Vec, IpcSender>), + /// Open file dialog to select files. Set boolean flag to true allows to select multiple files. + GetSelectedFiles(Vec, bool, IpcSender>>), /// Request to present an IME to the user when an editable element is focused. ShowIME(TopLevelBrowsingContextId, InputMethodType), /// Request to hide the IME when the editable element is blurred. @@ -248,6 +251,7 @@ impl Debug for EmbedderMsg { EmbedderMsg::LoadComplete(..) => write!(f, "LoadComplete"), EmbedderMsg::Panic(..) => write!(f, "Panic"), EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"), + EmbedderMsg::GetSelectedFiles(..) => write!(f, "SelectFileDialog"), EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"), EmbedderMsg::HideIME(..) => write!(f, "HideIME"), EmbedderMsg::Shutdown => write!(f, "Shutdown"), diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 1a8d8e825e0..048e0c7b740 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -115,6 +115,7 @@ use msg::constellation_msg::{BrowsingContextId, PipelineId, HistoryStateId, TopL use msg::constellation_msg::{Key, KeyModifiers, KeyState}; use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, TraversalDirection}; use net_traits::{self, IpcSend, FetchResponseMsg, ResourceThreads}; +use net_traits::filemanager_thread::FilterPattern; use net_traits::pub_domains::reg_host; use net_traits::request::RequestInit; use net_traits::storage_thread::{StorageThreadMsg, StorageType}; @@ -1013,7 +1014,7 @@ impl Constellation self.handle_set_cursor_msg(cursor) } FromCompositorMsg::OpenFileSelectDialog(patterns, multiple_files, sender) => { - return; + self.handle_open_file_select_dialog_msg(patterns, multiple_files, sender); } } } @@ -1741,6 +1742,14 @@ impl Constellation self.embedder_proxy.send(EmbedderMsg::SetCursor(cursor)) } + fn handle_open_file_select_dialog_msg(&mut self, + patterns: Vec, + multiple_files: bool, + sender: IpcSender>>) { + let msg = EmbedderMsg::GetSelectedFiles(patterns, multiple_files, sender); + self.embedder_proxy.send(msg); + } + fn handle_change_running_animations_state(&mut self, pipeline_id: PipelineId, animation_state: AnimationState) { diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index 429b59b189b..cf188dad4a7 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -294,6 +294,8 @@ impl Browser { }, EmbedderMsg::GetSelectedBluetoothDevice(devices, sender) => { platform_get_selected_devices(devices, sender); + }, + EmbedderMsg::GetSelectedFiles(patterns, multiple_files, sender) => { } EmbedderMsg::ShowIME(_browser_id, _kind) => { debug!("ShowIME received"); From 4125b54c0d1e27ad5090e246d1c877adc5b335b0 Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Fri, 30 Mar 2018 12:03:43 -0700 Subject: [PATCH 04/11] feat(browser): implement select file dialog --- ports/servo/browser.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index cf188dad4a7..afdaeb173c9 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -10,6 +10,7 @@ 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::filemanager_thread::FilterPattern; use servo::net_traits::pub_domains::is_reg_domain; use servo::script_traits::TouchEventType; use servo::servo_config::prefs::PREFS; @@ -17,7 +18,6 @@ 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; @@ -296,6 +296,7 @@ impl Browser { platform_get_selected_devices(devices, sender); }, EmbedderMsg::GetSelectedFiles(patterns, multiple_files, sender) => { + platform_get_selected_files(patterns, multiple_files, sender); } EmbedderMsg::ShowIME(_browser_id, _kind) => { debug!("ShowIME received"); @@ -342,6 +343,35 @@ fn platform_get_selected_devices(devices: Vec, sender: IpcSender, multiple_files: bool, sender: IpcSender>>) { + let picker_name = if multiple_files { "Pick files" } else { "Pick a file" }; + + thread::Builder::new().name(picker_name.to_owned()).spawn(move || { + let mut filter = vec![]; + for p in patterns { + let s = "*.".to_string() + &p.0; + filter.push(s) + } + + let filter_ref = &(filter.iter().map(|s| s.as_str()).collect::>()[..]); + let filter_opt = if filter.len() > 0 { Some((filter_ref, "")) } else { None }; + + if multiple_files { + let files = tinyfiledialogs::open_file_dialog_multi(picker_name, "", filter_opt); + let _ = sender.send(files); + } else { + let file = tinyfiledialogs::open_file_dialog(picker_name, "", filter_opt); + let _ = sender.send(file.map(|x| vec![x])); + } + }).expect("Thread spawning failed"); +} + +#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] +fn platform_get_selected_files(_patterns: Vec, _multiple_files: bool, sender: IpcSender>>) { + sender.send(None); +} + fn sanitize_url(request: &str) -> Option { let request = request.trim(); ServoUrl::parse(&request).ok() From f69b12444471937245bdde0dc54782e7296dc1ae Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Fri, 30 Mar 2018 12:06:31 -0700 Subject: [PATCH 05/11] refactor(filemanager): remove awareness to ui behavior --- Cargo.lock | 1 - components/net/Cargo.toml | 3 -- components/net/filemanager_thread.rs | 62 ---------------------------- components/net/lib.rs | 2 - components/net/resource_thread.rs | 4 +- 5 files changed, 1 insertion(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d2c1c8c77bd..f8b982fcc0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1920,7 +1920,6 @@ dependencies = [ "servo_url 0.0.1", "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "tinyfiledialogs 3.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (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/net/Cargo.toml b/components/net/Cargo.toml index 5e747577ada..7f1c402a4c0 100644 --- a/components/net/Cargo.toml +++ b/components/net/Cargo.toml @@ -49,9 +49,6 @@ url = "1.2" uuid = {version = "0.6", features = ["v4"]} webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} -[target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies] -tinyfiledialogs = "3.0" - [[test]] name = "main" path = "tests/main.rs" diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index bc433895ba9..97807f3f01e 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -21,71 +21,9 @@ use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering}; use std::sync::mpsc::Sender; use std::thread; #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] -use tinyfiledialogs; use url::Url; use uuid::Uuid; -/// The provider of file-dialog UI should implement this trait. -/// It will be used to initialize a generic FileManager. -/// For example, we can choose a dummy UI for testing purpose. -pub trait UIProvider where Self: Sync { - fn open_file_dialog(&self, path: &str, patterns: Vec) -> Option; - - fn open_file_dialog_multi(&self, path: &str, patterns: Vec) -> Option>; -} - -pub struct TFDProvider; - -impl UIProvider for TFDProvider { - #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] - fn open_file_dialog(&self, path: &str, patterns: Vec) -> Option { - if opts::get().headless { - return None; - } - - let mut filter = vec![]; - for p in patterns { - let s = "*.".to_string() + &p.0; - filter.push(s) - } - - let filter_ref = &(filter.iter().map(|s| s.as_str()).collect::>()[..]); - - let filter_opt = if filter.len() > 0 { Some((filter_ref, "")) } else { None }; - - tinyfiledialogs::open_file_dialog("Pick a file", path, filter_opt) - } - - #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] - fn open_file_dialog_multi(&self, path: &str, patterns: Vec) -> Option> { - if opts::get().headless { - return None; - } - - let mut filter = vec![]; - for p in patterns { - let s = "*.".to_string() + &p.0; - filter.push(s) - } - - let filter_ref = &(filter.iter().map(|s| s.as_str()).collect::>()[..]); - - let filter_opt = if filter.len() > 0 { Some((filter_ref, "")) } else { None }; - - tinyfiledialogs::open_file_dialog_multi("Pick files", path, filter_opt) - } - - #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] - fn open_file_dialog(&self, _path: &str, _patterns: Vec) -> Option { - None - } - - #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] - fn open_file_dialog_multi(&self, _path: &str, _patterns: Vec) -> Option> { - None - } -} - /// FileManagerStore's entry struct FileStoreEntry { /// Origin of the entry's "creator" diff --git a/components/net/lib.rs b/components/net/lib.rs index 1e17fd0988d..6bfde683494 100644 --- a/components/net/lib.rs +++ b/components/net/lib.rs @@ -37,8 +37,6 @@ extern crate servo_arc; extern crate servo_config; extern crate servo_url; extern crate time; -#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] -extern crate tinyfiledialogs; extern crate unicase; extern crate url; extern crate uuid; diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index fce89fd6624..6030f30dea4 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -11,7 +11,7 @@ use devtools_traits::DevtoolsControlMsg; use embedder_traits::resources::{self, Resource}; use fetch::cors_cache::CorsCache; use fetch::methods::{CancellationListener, FetchContext, fetch}; -use filemanager_thread::{FileManager, TFDProvider}; +use filemanager_thread::FileManager; use hsts::HstsList; use http_cache::HttpCache; use http_loader::{HttpState, http_redirect_fetch}; @@ -47,8 +47,6 @@ use std::thread; use storage_thread::StorageThreadFactory; use websocket_loader; -const TFD_PROVIDER: &'static TFDProvider = &TFDProvider; - /// Returns a tuple of (public, private) senders to the new threads. pub fn new_resource_threads(user_agent: Cow<'static, str>, devtools_chan: Option>, From c4c0d263e9aa4c4301f3a1499b5d4aa84e51436f Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Fri, 30 Mar 2018 12:15:57 -0700 Subject: [PATCH 06/11] test(net): update test cases --- components/net/tests/fetch.rs | 3 +- components/net/tests/filemanager_thread.rs | 35 +++++++--------------- components/net/tests/main.rs | 5 +++- components/net/tests/resource_thread.rs | 7 ++++- 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/components/net/tests/fetch.rs b/components/net/tests/fetch.rs index f8552b7654e..18607dc8cc2 100644 --- a/components/net/tests/fetch.rs +++ b/components/net/tests/fetch.rs @@ -552,12 +552,13 @@ fn test_fetch_with_hsts() { let mut ca_content = String::new(); File::open(cert_path).unwrap().read_to_string(&mut ca_content).unwrap(); let ssl_client = create_ssl_client(&ca_content); + let (sender, _) = channel(); let context = FetchContext { state: Arc::new(HttpState::new(ssl_client)), user_agent: DEFAULT_USER_AGENT.into(), devtools_chan: None, - filemanager: FileManager::new(), + filemanager: FileManager::new(sender), cancellation_listener: Arc::new(Mutex::new(CancellationListener::new(None))), }; diff --git a/components/net/tests/filemanager_thread.rs b/components/net/tests/filemanager_thread.rs index 089e56c43fb..557cbc0af45 100644 --- a/components/net/tests/filemanager_thread.rs +++ b/components/net/tests/filemanager_thread.rs @@ -3,30 +3,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use ipc_channel::ipc; -use net::filemanager_thread::{FileManager, UIProvider}; +use net::filemanager_thread::FileManager; use net_traits::blob_url_store::BlobURLStoreError; use net_traits::filemanager_thread::{FilterPattern, FileManagerThreadMsg, FileManagerThreadError, ReadFileProgress}; +use servo_config::prefs::{PrefValue, PREFS}; use std::fs::File; use std::io::Read; use std::path::PathBuf; - -pub const TEST_PROVIDER: &'static TestProvider = &TestProvider; - -pub struct TestProvider; - -impl UIProvider for TestProvider { - fn open_file_dialog(&self, _path: &str, _patterns: Vec) -> Option { - Some("tests/test.jpeg".to_string()) - } - - fn open_file_dialog_multi(&self, _path: &str, _patterns: Vec) -> Option> { - Some(vec!["tests/test.jpeg".to_string()]) - } -} +use std::sync::mpsc::channel; #[test] fn test_filemanager() { - let filemanager = FileManager::new(); + let (sender, _) = channel(); + let filemanager = FileManager::new(sender); + PREFS.set("dom.testing.htmlinputelement.select_files.enabled", PrefValue::Boolean(true)); // Try to open a dummy file "components/net/tests/test.jpeg" in tree let mut handler = File::open("tests/test.jpeg").expect("test.jpeg is stolen"); @@ -41,8 +31,8 @@ fn test_filemanager() { { // Try to select a dummy file "components/net/tests/test.jpeg" let (tx, rx) = ipc::channel().unwrap(); - filemanager.handle(FileManagerThreadMsg::SelectFile(patterns.clone(), tx, origin.clone(), None), - TEST_PROVIDER); + filemanager.handle(FileManagerThreadMsg::SelectFile(patterns.clone(), tx, origin.clone(), + Some("tests/test.jpeg".to_string()))); let selected = rx.recv().expect("Broken channel") .expect("The file manager failed to find test.jpeg"); @@ -53,8 +43,7 @@ fn test_filemanager() { // Test by reading, expecting same content { let (tx2, rx2) = ipc::channel().unwrap(); - filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone()), - TEST_PROVIDER); + filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone())); let msg = rx2.recv().expect("Broken channel"); @@ -84,8 +73,7 @@ fn test_filemanager() { // Delete the id { let (tx2, rx2) = ipc::channel().unwrap(); - filemanager.handle(FileManagerThreadMsg::DecRef(selected.id.clone(), origin.clone(), tx2), - TEST_PROVIDER); + filemanager.handle(FileManagerThreadMsg::DecRef(selected.id.clone(), origin.clone(), tx2)); let ret = rx2.recv().expect("Broken channel"); assert!(ret.is_ok(), "DecRef is not okay"); @@ -94,8 +82,7 @@ fn test_filemanager() { // Test by reading again, expecting read error because we invalidated the id { let (tx2, rx2) = ipc::channel().unwrap(); - filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone()), - TEST_PROVIDER); + filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone())); let msg = rx2.recv().expect("Broken channel"); diff --git a/components/net/tests/main.rs b/components/net/tests/main.rs index 4e2c4c97f58..2fe0e739923 100644 --- a/components/net/tests/main.rs +++ b/components/net/tests/main.rs @@ -16,6 +16,8 @@ extern crate msg; extern crate net; extern crate net_traits; extern crate profile_traits; +extern crate script_traits; +extern crate servo_config; extern crate servo_url; extern crate time; extern crate unicase; @@ -56,11 +58,12 @@ struct FetchResponseCollector { fn new_fetch_context(dc: Option>) -> FetchContext { let ssl_client = create_ssl_client(&resources::read_string(Resource::SSLCertificates)); + let (sender, _) = channel(); FetchContext { state: Arc::new(HttpState::new(ssl_client)), user_agent: DEFAULT_USER_AGENT.into(), devtools_chan: dc, - filemanager: FileManager::new(), + filemanager: FileManager::new(sender), cancellation_listener: Arc::new(Mutex::new(CancellationListener::new(None))), } } diff --git a/components/net/tests/resource_thread.rs b/components/net/tests/resource_thread.rs index adf1e305698..1e6c52378d9 100644 --- a/components/net/tests/resource_thread.rs +++ b/components/net/tests/resource_thread.rs @@ -8,7 +8,9 @@ use net::test::parse_hostsfile; use net_traits::CoreResourceMsg; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan; +use script_traits::ConstellationMsg; use std::net::IpAddr; +use std::sync::mpsc::channel; fn ip(s: &str) -> IpAddr { s.parse().unwrap() @@ -18,9 +20,12 @@ fn ip(s: &str) -> IpAddr { fn test_exit() { let (tx, _rx) = ipc::channel().unwrap(); let (mtx, _mrx) = ipc::channel().unwrap(); + let (constellation, _) = channel(); let (sender, receiver) = ipc::channel().unwrap(); - let (resource_thread, _private_resource_thread) = new_core_resource_thread( + let (resource_thread, _private_resource_thread, constellation_sender) = new_core_resource_thread( "".into(), None, ProfilerChan(tx), MemProfilerChan(mtx), None); + constellation_sender.send(constellation.clone()).unwrap(); + let _ = constellation.send(ConstellationMsg::Exit); resource_thread.send(CoreResourceMsg::Exit(sender)).unwrap(); receiver.recv().unwrap(); } From 52b9e4f0abf145ceb695d0b8f6addcef71b4bbac Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Tue, 3 Apr 2018 09:57:46 -0700 Subject: [PATCH 07/11] refactor(constellation): replace constellationmsg to filemanagermsg --- components/compositing/compositor_thread.rs | 2 +- components/constellation/constellation.rs | 46 ++++++++++++++------- components/script_traits/lib.rs | 5 +-- components/script_traits/script_msg.rs | 8 ++++ 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index f4aa96c20b9..d4d177c29e1 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -251,7 +251,7 @@ impl Debug for EmbedderMsg { EmbedderMsg::LoadComplete(..) => write!(f, "LoadComplete"), EmbedderMsg::Panic(..) => write!(f, "Panic"), EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"), - EmbedderMsg::GetSelectedFiles(..) => write!(f, "SelectFileDialog"), + EmbedderMsg::GetSelectedFiles(..) => write!(f, "GetSelectedFiles"), EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"), EmbedderMsg::HideIME(..) => write!(f, "HideIME"), EmbedderMsg::Shutdown => write!(f, "Shutdown"), diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 048e0c7b740..0f1e6a37393 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -115,7 +115,6 @@ use msg::constellation_msg::{BrowsingContextId, PipelineId, HistoryStateId, TopL use msg::constellation_msg::{Key, KeyModifiers, KeyState}; use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, TraversalDirection}; use net_traits::{self, IpcSend, FetchResponseMsg, ResourceThreads}; -use net_traits::filemanager_thread::FilterPattern; use net_traits::pub_domains::reg_host; use net_traits::request::RequestInit; use net_traits::storage_thread::{StorageThreadMsg, StorageType}; @@ -126,10 +125,10 @@ use profile_traits::time; use script_traits::{AnimationState, AnimationTickType, CompositorEvent}; use script_traits::{ConstellationControlMsg, ConstellationMsg as FromCompositorMsg, DiscardBrowsingContext}; use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData}; +use script_traits::{FileManagerMsg, SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WebDriverCommandMsg}; use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg}; use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory}; use script_traits::{LogEntry, ScriptToConstellationChan, ServiceWorkerMsg, webdriver_msg}; -use script_traits::{SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WebDriverCommandMsg}; use script_traits::{WindowSizeData, WindowSizeType}; use serde::{Deserialize, Serialize}; use servo_config::opts; @@ -175,6 +174,10 @@ pub struct Constellation { /// This is the constellation's view of `script_sender`. script_receiver: Receiver>, + /// A channel for the constellation to receive messages from filemanager threads. + /// This is the constellation's view of `filemanager_sender`. + filemanager_receiver: Receiver>, + /// An IPC channel for layout threads to send messages to the constellation. /// This is the layout threads' view of `layout_receiver`. layout_sender: IpcSender, @@ -547,17 +550,22 @@ impl Constellation STF: ScriptThreadFactory { /// Create a new constellation thread. - pub fn start(state: InitialConstellationState) -> (Sender, IpcSender) { + pub fn start(state: InitialConstellationState) + -> (Sender, IpcSender, IpcSender) { let (compositor_sender, compositor_receiver) = channel(); // service worker manager to communicate with constellation let (swmanager_sender, swmanager_receiver) = ipc::channel().expect("ipc channel failure"); let sw_mgr_clone = swmanager_sender.clone(); + let (filemanager_sender, filemanager_receiver) = ipc::channel().expect("ipc channel failure"); + thread::Builder::new().name("Constellation".to_owned()).spawn(move || { let (ipc_script_sender, ipc_script_receiver) = ipc::channel().expect("ipc channel failure"); let script_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_script_receiver); + let filemanager_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(filemanager_receiver); + let (ipc_layout_sender, ipc_layout_receiver) = ipc::channel().expect("ipc channel failure"); let layout_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_layout_receiver); @@ -571,6 +579,7 @@ impl Constellation script_sender: ipc_script_sender, layout_sender: ipc_layout_sender, script_receiver: script_receiver, + filemanager_receiver: filemanager_receiver, compositor_receiver: compositor_receiver, layout_receiver: layout_receiver, network_listener_sender: network_listener_sender, @@ -637,7 +646,7 @@ impl Constellation constellation.run(); }).expect("Thread spawning failed"); - (compositor_sender, swmanager_sender) + (compositor_sender, swmanager_sender, filemanager_sender) } /// The main event loop for the constellation. @@ -831,6 +840,7 @@ impl Constellation Layout(FromLayoutMsg), NetworkListener((PipelineId, FetchResponseMsg)), FromSWManager(SWManagerMsg), + FromFileManager(FileManagerMsg), } // Get one incoming request. @@ -850,6 +860,7 @@ impl Constellation let receiver_from_layout = &self.layout_receiver; let receiver_from_network_listener = &self.network_listener_receiver; let receiver_from_swmanager = &self.swmanager_receiver; + let receiver_from_filemanager = &self.filemanager_receiver; select! { msg = receiver_from_script.recv() => msg.expect("Unexpected script channel panic in constellation").map(Request::Script), @@ -862,7 +873,9 @@ impl Constellation msg.expect("Unexpected network listener channel panic in constellation") )), msg = receiver_from_swmanager.recv() => - msg.expect("Unexpected panic channel panic in constellation").map(Request::FromSWManager) + msg.expect("Unexpected panic channel panic in constellation").map(Request::FromSWManager), + msg = receiver_from_filemanager.recv() => + msg.expect("Unexpected file manager channel panic in constellation").map(Request::FromFileManager) } }; @@ -886,6 +899,9 @@ impl Constellation }, Request::FromSWManager(message) => { self.handle_request_from_swmanager(message); + }, + Request::FromFileManager(message) => { + self.handle_request_from_filemanager(message); } } } @@ -915,6 +931,15 @@ impl Constellation } } + fn handle_request_from_filemanager(&mut self, message: FileManagerMsg) { + match message { + FileManagerMsg::OpenFileSelectDialog(patterns, multiple_files, sender) => { + let msg = EmbedderMsg::GetSelectedFiles(patterns, multiple_files, sender); + self.embedder_proxy.send(msg); + } + } + } + fn handle_request_from_compositor(&mut self, message: FromCompositorMsg) { match message { FromCompositorMsg::Exit => { @@ -1013,9 +1038,6 @@ impl Constellation FromCompositorMsg::SetCursor(cursor) => { self.handle_set_cursor_msg(cursor) } - FromCompositorMsg::OpenFileSelectDialog(patterns, multiple_files, sender) => { - self.handle_open_file_select_dialog_msg(patterns, multiple_files, sender); - } } } @@ -1742,14 +1764,6 @@ impl Constellation self.embedder_proxy.send(EmbedderMsg::SetCursor(cursor)) } - fn handle_open_file_select_dialog_msg(&mut self, - patterns: Vec, - multiple_files: bool, - sender: IpcSender>>) { - let msg = EmbedderMsg::GetSelectedFiles(patterns, multiple_files, sender); - self.embedder_proxy.send(msg); - } - fn handle_change_running_animations_state(&mut self, pipeline_id: PipelineId, animation_state: AnimationState) { diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 584798caf0e..b2cf6a97e43 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -51,7 +51,6 @@ use libc::c_void; use msg::constellation_msg::{BrowsingContextId, HistoryStateId, Key, KeyModifiers, KeyState, PipelineId}; use msg::constellation_msg::{PipelineNamespaceId, TraversalDirection, TopLevelBrowsingContextId}; use net_traits::{FetchResponseMsg, ReferrerPolicy, ResourceThreads}; -use net_traits::filemanager_thread::FilterPattern; use net_traits::image::base::Image; use net_traits::image::base::PixelFormat; use net_traits::image_cache::ImageCache; @@ -74,7 +73,7 @@ use webrender_api::{ExternalScrollId, DevicePixel, DeviceUintSize, DocumentId, I use webvr_traits::{WebVREvent, WebVRMsg}; pub use script_msg::{LayoutMsg, ScriptMsg, EventResult, LogEntry}; -pub use script_msg::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders, DOMMessage}; +pub use script_msg::{FileManagerMsg, ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders, DOMMessage}; /// The address of a node. Layout sends these back. They must be validated via /// `from_untrusted_node_address` before they can be used, because we do not trust layout. @@ -706,8 +705,6 @@ pub enum ConstellationMsg { ForwardEvent(PipelineId, CompositorEvent), /// Requesting a change to the onscreen cursor. SetCursor(CursorKind), - /// Requesting to open file select dialog - OpenFileSelectDialog(Vec, bool, IpcSender>>), } /// Resources required by workerglobalscopes diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs index d263753c7de..9df1e7ee077 100644 --- a/components/script_traits/script_msg.rs +++ b/components/script_traits/script_msg.rs @@ -19,6 +19,7 @@ use ipc_channel::ipc::{IpcReceiver, IpcSender}; use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TraversalDirection}; use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState}; use net_traits::CoreResourceMsg; +use net_traits::filemanager_thread::FilterPattern; use net_traits::request::RequestInit; use net_traits::storage_thread::StorageType; use servo_url::ImmutableOrigin; @@ -217,3 +218,10 @@ pub enum SWManagerMsg { /// Provide the constellation with a means of communicating with the Service Worker Manager OwnSender(IpcSender), } + +/// Messages outgoing from the File Manager thread to constellation +#[derive(Deserialize, Serialize)] +pub enum FileManagerMsg { + /// Requesting to open file select dialog + OpenFileSelectDialog(Vec, bool, IpcSender>>) +} From 7cec47b3fadcd645fa746432d14a04e356ead176 Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Tue, 3 Apr 2018 10:00:06 -0700 Subject: [PATCH 08/11] refactor(filemanager): use filemanagermsg to request embedder --- components/net/filemanager_thread.rs | 15 +++++++-------- components/net/resource_thread.rs | 12 ++++++------ components/servo/lib.rs | 4 ++-- ports/servo/browser.rs | 9 +++++++-- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index 97807f3f01e..5c59a6aae8c 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -7,7 +7,7 @@ use mime_guess::guess_mime_type_opt; use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError}; use net_traits::filemanager_thread::{FileManagerResult, FileManagerThreadMsg, FileOrigin, FilterPattern}; use net_traits::filemanager_thread::{FileManagerThreadError, ReadFileProgress, RelativePos, SelectedFile}; -use script_traits::ConstellationMsg; +use script_traits::FileManagerMsg; #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use servo_config::opts; use servo_config::prefs::PREFS; @@ -18,7 +18,6 @@ use std::ops::Index; use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering}; -use std::sync::mpsc::Sender; use std::thread; #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use url::Url; @@ -63,12 +62,12 @@ enum FileImpl { #[derive(Clone)] pub struct FileManager { - constellation_chan: Sender, + constellation_chan: IpcSender, store: Arc, } impl FileManager { - pub fn new(constellation_chan: Sender) -> FileManager { + pub fn new(constellation_chan: IpcSender) -> FileManager { FileManager { constellation_chan: constellation_chan, store: Arc::new(FileManagerStore::new()), @@ -222,13 +221,13 @@ impl FileManagerStore { fn get_selected_files(&self, patterns: Vec, multiple_files: bool, - constellation_chan: Sender) -> Option> { + constellation_chan: IpcSender) -> Option> { if opts::get().headless { return None; } let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); - let msg = ConstellationMsg::OpenFileSelectDialog(patterns, multiple_files, ipc_sender); + let msg = FileManagerMsg::OpenFileSelectDialog(patterns, multiple_files, ipc_sender); constellation_chan.send(msg).map(|_| ipc_receiver.recv().unwrap()).unwrap_or_default() } @@ -238,7 +237,7 @@ impl FileManagerStore { sender: IpcSender>, origin: FileOrigin, opt_test_path: Option, - constellation_chan: Sender) { + constellation_chan: IpcSender) { // Check if the select_files preference is enabled // to ensure process-level security against compromised script; // Then try applying opt_test_path directly for testing convenience @@ -266,7 +265,7 @@ impl FileManagerStore { sender: IpcSender>>, origin: FileOrigin, opt_test_paths: Option>, - constellation_chan: Sender) { + constellation_chan: IpcSender) { // Check if the select_files preference is enabled // to ensure process-level security against compromised script; // Then try applying opt_test_paths directly for testing convenience diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index 6030f30dea4..3f3e8c10843 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -28,7 +28,7 @@ use net_traits::storage_thread::StorageThreadMsg; use profile_traits::mem::{Report, ReportsChan, ReportKind}; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan; -use script_traits::ConstellationMsg; +use script_traits::FileManagerMsg; use serde::{Deserialize, Serialize}; use serde_json; use servo_allocator; @@ -42,7 +42,7 @@ use std::io::prelude::*; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex, RwLock}; -use std::sync::mpsc::{self, Sender}; +use std::sync::mpsc::Sender; use std::thread; use storage_thread::StorageThreadFactory; use websocket_loader; @@ -53,7 +53,7 @@ pub fn new_resource_threads(user_agent: Cow<'static, str>, time_profiler_chan: ProfilerChan, mem_profiler_chan: MemProfilerChan, config_dir: Option) - -> (ResourceThreads, ResourceThreads, Sender>) { + -> (ResourceThreads, ResourceThreads, IpcSender>) { let (public_core, private_core, constellation_sender) = new_core_resource_thread( user_agent, devtools_chan, @@ -73,11 +73,11 @@ pub fn new_core_resource_thread(user_agent: Cow<'static, str>, time_profiler_chan: ProfilerChan, mem_profiler_chan: MemProfilerChan, config_dir: Option) - -> (CoreResourceThread, CoreResourceThread, Sender>) { + -> (CoreResourceThread, CoreResourceThread, IpcSender>) { let (public_setup_chan, public_setup_port) = ipc::channel().unwrap(); let (private_setup_chan, private_setup_port) = ipc::channel().unwrap(); let (report_chan, report_port) = ipc::channel().unwrap(); - let (constellation_sender, constellation_receiver) = mpsc::channel(); + let (constellation_sender, constellation_receiver) = ipc::channel().unwrap(); thread::Builder::new().name("ResourceManager".to_owned()).spawn(move || { let constellation_chan = constellation_receiver.recv().unwrap(); @@ -377,7 +377,7 @@ impl CoreResourceManager { pub fn new(user_agent: Cow<'static, str>, devtools_channel: Option>, _profiler_chan: ProfilerChan, - constellation_chan: Sender) -> CoreResourceManager { + constellation_chan: IpcSender) -> CoreResourceManager { CoreResourceManager { user_agent: user_agent, devtools_chan: devtools_channel, diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 4fd94207b47..65449d0d9af 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -523,7 +523,7 @@ fn create_constellation(user_agent: Cow<'static, str>, webgl_threads, webvr_chan, }; - let (constellation_chan, from_swmanager_sender) = + let (constellation_chan, from_swmanager_sender, from_filemanager_sender) = Constellation::::start(initial_state); @@ -533,7 +533,7 @@ fn create_constellation(user_agent: Cow<'static, str>, webvr_constellation_sender.send(constellation_chan.clone()).unwrap(); } - resource_constellation_sender.send(constellation_chan.clone()).unwrap(); + resource_constellation_sender.send(from_filemanager_sender.clone()).unwrap(); // channels to communicate with Service Worker Manager let sw_senders = SWManagerSenders { diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index afdaeb173c9..b1f2627fb68 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -18,6 +18,7 @@ use servo::servo_url::ServoUrl; use servo::webrender_api::ScrollLocation; use std::mem; use std::rc::Rc; +#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use std::thread; use tinyfiledialogs; @@ -344,7 +345,9 @@ fn platform_get_selected_devices(devices: Vec, sender: IpcSender, multiple_files: bool, sender: IpcSender>>) { +fn platform_get_selected_files(patterns: Vec, + multiple_files: bool, + sender: IpcSender>>) { let picker_name = if multiple_files { "Pick files" } else { "Pick a file" }; thread::Builder::new().name(picker_name.to_owned()).spawn(move || { @@ -368,7 +371,9 @@ fn platform_get_selected_files(patterns: Vec, multiple_files: boo } #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] -fn platform_get_selected_files(_patterns: Vec, _multiple_files: bool, sender: IpcSender>>) { +fn platform_get_selected_files(_patterns: Vec, + _multiple_files: bool, + sender: IpcSender>>) { sender.send(None); } From 2fab94785becfc5a7c8922d283be426795a43b6d Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Sat, 14 Apr 2018 10:29:09 -0700 Subject: [PATCH 09/11] refactor(filemanager): uses embedderproxy directly --- Cargo.lock | 2 +- components/constellation/constellation.rs | 34 ++------------- components/net/Cargo.toml | 2 +- components/net/filemanager_thread.rs | 50 +++++++++++------------ components/net/lib.rs | 2 +- components/net/resource_thread.rs | 24 +++++------ components/script_traits/lib.rs | 2 +- components/script_traits/script_msg.rs | 8 ---- components/servo/lib.rs | 7 ++-- ports/servo/browser.rs | 7 +++- 10 files changed, 54 insertions(+), 84 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8b982fcc0e..9d8da41369e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1890,6 +1890,7 @@ version = "0.0.1" dependencies = [ "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "brotli 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "compositing 0.0.1", "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "embedder_traits 0.0.1", @@ -1910,7 +1911,6 @@ dependencies = [ "net_traits 0.0.1", "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", "profile_traits 0.0.1", - "script_traits 0.0.1", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "servo-websocket 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 0f1e6a37393..93581d9f884 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -125,10 +125,10 @@ use profile_traits::time; use script_traits::{AnimationState, AnimationTickType, CompositorEvent}; use script_traits::{ConstellationControlMsg, ConstellationMsg as FromCompositorMsg, DiscardBrowsingContext}; use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData}; -use script_traits::{FileManagerMsg, SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WebDriverCommandMsg}; use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg}; use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory}; use script_traits::{LogEntry, ScriptToConstellationChan, ServiceWorkerMsg, webdriver_msg}; +use script_traits::{SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WebDriverCommandMsg}; use script_traits::{WindowSizeData, WindowSizeType}; use serde::{Deserialize, Serialize}; use servo_config::opts; @@ -174,10 +174,6 @@ pub struct Constellation { /// This is the constellation's view of `script_sender`. script_receiver: Receiver>, - /// A channel for the constellation to receive messages from filemanager threads. - /// This is the constellation's view of `filemanager_sender`. - filemanager_receiver: Receiver>, - /// An IPC channel for layout threads to send messages to the constellation. /// This is the layout threads' view of `layout_receiver`. layout_sender: IpcSender, @@ -550,22 +546,17 @@ impl Constellation STF: ScriptThreadFactory { /// Create a new constellation thread. - pub fn start(state: InitialConstellationState) - -> (Sender, IpcSender, IpcSender) { + pub fn start(state: InitialConstellationState) -> (Sender, IpcSender) { let (compositor_sender, compositor_receiver) = channel(); // service worker manager to communicate with constellation let (swmanager_sender, swmanager_receiver) = ipc::channel().expect("ipc channel failure"); let sw_mgr_clone = swmanager_sender.clone(); - let (filemanager_sender, filemanager_receiver) = ipc::channel().expect("ipc channel failure"); - thread::Builder::new().name("Constellation".to_owned()).spawn(move || { let (ipc_script_sender, ipc_script_receiver) = ipc::channel().expect("ipc channel failure"); let script_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_script_receiver); - let filemanager_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(filemanager_receiver); - let (ipc_layout_sender, ipc_layout_receiver) = ipc::channel().expect("ipc channel failure"); let layout_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_layout_receiver); @@ -579,7 +570,6 @@ impl Constellation script_sender: ipc_script_sender, layout_sender: ipc_layout_sender, script_receiver: script_receiver, - filemanager_receiver: filemanager_receiver, compositor_receiver: compositor_receiver, layout_receiver: layout_receiver, network_listener_sender: network_listener_sender, @@ -646,7 +636,7 @@ impl Constellation constellation.run(); }).expect("Thread spawning failed"); - (compositor_sender, swmanager_sender, filemanager_sender) + (compositor_sender, swmanager_sender) } /// The main event loop for the constellation. @@ -840,7 +830,6 @@ impl Constellation Layout(FromLayoutMsg), NetworkListener((PipelineId, FetchResponseMsg)), FromSWManager(SWManagerMsg), - FromFileManager(FileManagerMsg), } // Get one incoming request. @@ -860,7 +849,6 @@ impl Constellation let receiver_from_layout = &self.layout_receiver; let receiver_from_network_listener = &self.network_listener_receiver; let receiver_from_swmanager = &self.swmanager_receiver; - let receiver_from_filemanager = &self.filemanager_receiver; select! { msg = receiver_from_script.recv() => msg.expect("Unexpected script channel panic in constellation").map(Request::Script), @@ -873,9 +861,7 @@ impl Constellation msg.expect("Unexpected network listener channel panic in constellation") )), msg = receiver_from_swmanager.recv() => - msg.expect("Unexpected panic channel panic in constellation").map(Request::FromSWManager), - msg = receiver_from_filemanager.recv() => - msg.expect("Unexpected file manager channel panic in constellation").map(Request::FromFileManager) + msg.expect("Unexpected panic channel panic in constellation").map(Request::FromSWManager) } }; @@ -899,9 +885,6 @@ impl Constellation }, Request::FromSWManager(message) => { self.handle_request_from_swmanager(message); - }, - Request::FromFileManager(message) => { - self.handle_request_from_filemanager(message); } } } @@ -931,15 +914,6 @@ impl Constellation } } - fn handle_request_from_filemanager(&mut self, message: FileManagerMsg) { - match message { - FileManagerMsg::OpenFileSelectDialog(patterns, multiple_files, sender) => { - let msg = EmbedderMsg::GetSelectedFiles(patterns, multiple_files, sender); - self.embedder_proxy.send(msg); - } - } - } - fn handle_request_from_compositor(&mut self, message: FromCompositorMsg) { match message { FromCompositorMsg::Exit => { diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml index 7f1c402a4c0..4aaeecf75d9 100644 --- a/components/net/Cargo.toml +++ b/components/net/Cargo.toml @@ -15,6 +15,7 @@ doctest = false base64 = "0.6" brotli = "1.0.6" cookie = "0.10" +compositing = {path = "../compositing"} devtools_traits = {path = "../devtools_traits"} embedder_traits = { path = "../embedder_traits" } flate2 = "1" @@ -34,7 +35,6 @@ msg = {path = "../msg"} net_traits = {path = "../net_traits"} openssl = "0.9" profile_traits = {path = "../profile_traits"} -script_traits = {path = "../script_traits"} serde = "1.0" serde_json = "1.0" servo_allocator = {path = "../allocator"} diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index 5c59a6aae8c..0e5d8dafd75 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -2,14 +2,12 @@ * 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 compositing::compositor_thread::{EmbedderMsg, EmbedderProxy}; use ipc_channel::ipc::{self, IpcSender}; use mime_guess::guess_mime_type_opt; use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError}; use net_traits::filemanager_thread::{FileManagerResult, FileManagerThreadMsg, FileOrigin, FilterPattern}; use net_traits::filemanager_thread::{FileManagerThreadError, ReadFileProgress, RelativePos, SelectedFile}; -use script_traits::FileManagerMsg; -#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] -use servo_config::opts; use servo_config::prefs::PREFS; use std::collections::HashMap; use std::fs::File; @@ -19,7 +17,6 @@ use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering}; use std::thread; -#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use url::Url; use uuid::Uuid; @@ -62,14 +59,14 @@ enum FileImpl { #[derive(Clone)] pub struct FileManager { - constellation_chan: IpcSender, + embedder_proxy: EmbedderProxy, store: Arc, } impl FileManager { - pub fn new(constellation_chan: IpcSender) -> FileManager { + pub fn new(embedder_proxy: EmbedderProxy) -> FileManager { FileManager { - constellation_chan: constellation_chan, + embedder_proxy: embedder_proxy, store: Arc::new(FileManagerStore::new()), } } @@ -104,16 +101,16 @@ impl FileManager { match msg { FileManagerThreadMsg::SelectFile(filter, sender, origin, opt_test_path) => { let store = self.store.clone(); - let constellation_chan = self.constellation_chan.clone(); + let embedder = self.embedder_proxy.clone(); thread::Builder::new().name("select file".to_owned()).spawn(move || { - store.select_file(filter, sender, origin, opt_test_path, constellation_chan); + store.select_file(filter, sender, origin, opt_test_path, embedder); }).expect("Thread spawning failed"); } FileManagerThreadMsg::SelectFiles(filter, sender, origin, opt_test_paths) => { let store = self.store.clone(); - let constellation_chan = self.constellation_chan.clone(); + let embedder = self.embedder_proxy.clone(); thread::Builder::new().name("select files".to_owned()).spawn(move || { - store.select_files(filter, sender, origin, opt_test_paths, constellation_chan); + store.select_files(filter, sender, origin, opt_test_paths, embedder); }).expect("Thread spawning failed"); } FileManagerThreadMsg::ReadFile(sender, id, check_url_validity, origin) => { @@ -218,18 +215,21 @@ impl FileManagerStore { } } - fn get_selected_files(&self, - patterns: Vec, - multiple_files: bool, - constellation_chan: IpcSender) -> Option> { - if opts::get().headless { - return None; - } - + fn query_files_from_embedder(&self, + patterns: Vec, + multiple_files: bool, + embedder_proxy: EmbedderProxy) -> Option> { let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); - let msg = FileManagerMsg::OpenFileSelectDialog(patterns, multiple_files, ipc_sender); + let msg = EmbedderMsg::GetSelectedFiles(patterns, multiple_files, ipc_sender); - constellation_chan.send(msg).map(|_| ipc_receiver.recv().unwrap()).unwrap_or_default() + embedder_proxy.send(msg); + match ipc_receiver.recv() { + Ok(result) => result, + Err(e) => { + warn!("Failed to receive files from embedder ({}).", e); + None + } + } } fn select_file(&self, @@ -237,14 +237,14 @@ impl FileManagerStore { sender: IpcSender>, origin: FileOrigin, opt_test_path: Option, - constellation_chan: IpcSender) { + embedder_proxy: EmbedderProxy) { // Check if the select_files preference is enabled // to ensure process-level security against compromised script; // Then try applying opt_test_path directly for testing convenience let opt_s = if select_files_pref_enabled() { opt_test_path } else { - self.get_selected_files(patterns, false, constellation_chan).map(|mut x| x.pop().unwrap()) + self.query_files_from_embedder(patterns, false, embedder_proxy).and_then(|mut x| x.pop()) }; match opt_s { @@ -265,14 +265,14 @@ impl FileManagerStore { sender: IpcSender>>, origin: FileOrigin, opt_test_paths: Option>, - constellation_chan: IpcSender) { + embedder_proxy: EmbedderProxy) { // Check if the select_files preference is enabled // to ensure process-level security against compromised script; // Then try applying opt_test_paths directly for testing convenience let opt_v = if select_files_pref_enabled() { opt_test_paths } else { - self.get_selected_files(patterns, true, constellation_chan) + self.query_files_from_embedder(patterns, true, embedder_proxy) }; match opt_v { diff --git a/components/net/lib.rs b/components/net/lib.rs index 6bfde683494..a8d802ae49f 100644 --- a/components/net/lib.rs +++ b/components/net/lib.rs @@ -6,6 +6,7 @@ extern crate base64; extern crate brotli; +extern crate compositing; extern crate cookie as cookie_rs; extern crate devtools_traits; extern crate embedder_traits; @@ -29,7 +30,6 @@ extern crate net_traits; extern crate openssl; #[macro_use] extern crate profile_traits; -extern crate script_traits; #[macro_use] extern crate serde; extern crate serde_json; extern crate servo_allocator; diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index 3f3e8c10843..d00c0323f38 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //! A thread that takes a URL and streams back the binary data. +use compositing::compositor_thread::EmbedderProxy; use connector::{create_http_connector, create_ssl_client}; use cookie; use cookie_rs; @@ -28,7 +29,6 @@ use net_traits::storage_thread::StorageThreadMsg; use profile_traits::mem::{Report, ReportsChan, ReportKind}; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan; -use script_traits::FileManagerMsg; use serde::{Deserialize, Serialize}; use serde_json; use servo_allocator; @@ -52,18 +52,19 @@ pub fn new_resource_threads(user_agent: Cow<'static, str>, devtools_chan: Option>, time_profiler_chan: ProfilerChan, mem_profiler_chan: MemProfilerChan, + embedder_proxy: EmbedderProxy, config_dir: Option) - -> (ResourceThreads, ResourceThreads, IpcSender>) { - let (public_core, private_core, constellation_sender) = new_core_resource_thread( + -> (ResourceThreads, ResourceThreads) { + let (public_core, private_core) = new_core_resource_thread( user_agent, devtools_chan, time_profiler_chan, mem_profiler_chan, + embedder_proxy, config_dir.clone()); let storage: IpcSender = StorageThreadFactory::new(config_dir); (ResourceThreads::new(public_core, storage.clone()), - ResourceThreads::new(private_core, storage), - constellation_sender) + ResourceThreads::new(private_core, storage)) } @@ -72,17 +73,16 @@ pub fn new_core_resource_thread(user_agent: Cow<'static, str>, devtools_chan: Option>, time_profiler_chan: ProfilerChan, mem_profiler_chan: MemProfilerChan, + embedder_proxy: EmbedderProxy, config_dir: Option) - -> (CoreResourceThread, CoreResourceThread, IpcSender>) { + -> (CoreResourceThread, CoreResourceThread) { let (public_setup_chan, public_setup_port) = ipc::channel().unwrap(); let (private_setup_chan, private_setup_port) = ipc::channel().unwrap(); let (report_chan, report_port) = ipc::channel().unwrap(); - let (constellation_sender, constellation_receiver) = ipc::channel().unwrap(); thread::Builder::new().name("ResourceManager".to_owned()).spawn(move || { - let constellation_chan = constellation_receiver.recv().unwrap(); let resource_manager = CoreResourceManager::new( - user_agent, devtools_chan, time_profiler_chan, constellation_chan + user_agent, devtools_chan, time_profiler_chan, embedder_proxy ); let mut channel_manager = ResourceChannelManager { @@ -101,7 +101,7 @@ pub fn new_core_resource_thread(user_agent: Cow<'static, str>, |report_chan| report_chan); }).expect("Thread spawning failed"); - (public_setup_chan, private_setup_chan, constellation_sender) + (public_setup_chan, private_setup_chan) } struct ResourceChannelManager { @@ -377,12 +377,12 @@ impl CoreResourceManager { pub fn new(user_agent: Cow<'static, str>, devtools_channel: Option>, _profiler_chan: ProfilerChan, - constellation_chan: IpcSender) -> CoreResourceManager { + embedder_proxy: EmbedderProxy) -> CoreResourceManager { CoreResourceManager { user_agent: user_agent, devtools_chan: devtools_channel, swmanager_chan: None, - filemanager: FileManager::new(constellation_chan), + filemanager: FileManager::new(embedder_proxy), } } diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index b2cf6a97e43..272cfe3cedb 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -73,7 +73,7 @@ use webrender_api::{ExternalScrollId, DevicePixel, DeviceUintSize, DocumentId, I use webvr_traits::{WebVREvent, WebVRMsg}; pub use script_msg::{LayoutMsg, ScriptMsg, EventResult, LogEntry}; -pub use script_msg::{FileManagerMsg, ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders, DOMMessage}; +pub use script_msg::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders, DOMMessage}; /// The address of a node. Layout sends these back. They must be validated via /// `from_untrusted_node_address` before they can be used, because we do not trust layout. diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs index 9df1e7ee077..d263753c7de 100644 --- a/components/script_traits/script_msg.rs +++ b/components/script_traits/script_msg.rs @@ -19,7 +19,6 @@ use ipc_channel::ipc::{IpcReceiver, IpcSender}; use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TraversalDirection}; use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState}; use net_traits::CoreResourceMsg; -use net_traits::filemanager_thread::FilterPattern; use net_traits::request::RequestInit; use net_traits::storage_thread::StorageType; use servo_url::ImmutableOrigin; @@ -218,10 +217,3 @@ pub enum SWManagerMsg { /// Provide the constellation with a means of communicating with the Service Worker Manager OwnSender(IpcSender), } - -/// Messages outgoing from the File Manager thread to constellation -#[derive(Deserialize, Serialize)] -pub enum FileManagerMsg { - /// Requesting to open file select dialog - OpenFileSelectDialog(Vec, bool, IpcSender>>) -} diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 65449d0d9af..bc06dc84ca7 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -457,11 +457,12 @@ fn create_constellation(user_agent: Cow<'static, str>, -> (Sender, SWManagerSenders) { let bluetooth_thread: IpcSender = BluetoothThreadFactory::new(embedder_proxy.clone()); - let (public_resource_threads, private_resource_threads, resource_constellation_sender) = + let (public_resource_threads, private_resource_threads) = new_resource_threads(user_agent, devtools_chan.clone(), time_profiler_chan.clone(), mem_profiler_chan.clone(), + embedder_proxy.clone(), config_dir); let font_cache_thread = FontCacheThread::new(public_resource_threads.sender(), webrender_api_sender.create_api()); @@ -523,7 +524,7 @@ fn create_constellation(user_agent: Cow<'static, str>, webgl_threads, webvr_chan, }; - let (constellation_chan, from_swmanager_sender, from_filemanager_sender) = + let (constellation_chan, from_swmanager_sender) = Constellation::::start(initial_state); @@ -533,8 +534,6 @@ fn create_constellation(user_agent: Cow<'static, str>, webvr_constellation_sender.send(constellation_chan.clone()).unwrap(); } - resource_constellation_sender.send(from_filemanager_sender.clone()).unwrap(); - // channels to communicate with Service Worker Manager let sw_senders = SWManagerSenders { swmanager_sender: from_swmanager_sender, diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index b1f2627fb68..62028867c94 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -13,6 +13,7 @@ use servo::msg::constellation_msg::{KeyModifiers, KeyState, TraversalDirection}; use servo::net_traits::filemanager_thread::FilterPattern; use servo::net_traits::pub_domains::is_reg_domain; use servo::script_traits::TouchEventType; +use servo::servo_config::opts; use servo::servo_config::prefs::PREFS; use servo::servo_url::ServoUrl; use servo::webrender_api::ScrollLocation; @@ -297,6 +298,9 @@ impl Browser { platform_get_selected_devices(devices, sender); }, EmbedderMsg::GetSelectedFiles(patterns, multiple_files, sender) => { + if opts::get().headless { + let _ = sender.send(None); + } platform_get_selected_files(patterns, multiple_files, sender); } EmbedderMsg::ShowIME(_browser_id, _kind) => { @@ -374,7 +378,8 @@ fn platform_get_selected_files(patterns: Vec, fn platform_get_selected_files(_patterns: Vec, _multiple_files: bool, sender: IpcSender>>) { - sender.send(None); + warn!("File picker not implemented"); + let _ = sender.send(None); } fn sanitize_url(request: &str) -> Option { From 9ff11b9af373997e847f7820a3ea37181845f926 Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Mon, 16 Apr 2018 00:21:21 -0700 Subject: [PATCH 10/11] refactor(embedder): rename file select message --- components/compositing/compositor_thread.rs | 4 ++-- components/net/filemanager_thread.rs | 2 +- ports/servo/browser.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index d4d177c29e1..2e8dc7a66d6 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -145,7 +145,7 @@ pub enum EmbedderMsg { /// Open dialog to select bluetooth device. GetSelectedBluetoothDevice(Vec, IpcSender>), /// Open file dialog to select files. Set boolean flag to true allows to select multiple files. - GetSelectedFiles(Vec, bool, IpcSender>>), + SelectFiles(Vec, bool, IpcSender>>), /// Request to present an IME to the user when an editable element is focused. ShowIME(TopLevelBrowsingContextId, InputMethodType), /// Request to hide the IME when the editable element is blurred. @@ -251,7 +251,7 @@ impl Debug for EmbedderMsg { EmbedderMsg::LoadComplete(..) => write!(f, "LoadComplete"), EmbedderMsg::Panic(..) => write!(f, "Panic"), EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"), - EmbedderMsg::GetSelectedFiles(..) => write!(f, "GetSelectedFiles"), + EmbedderMsg::SelectFiles(..) => write!(f, "SelectFiles"), EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"), EmbedderMsg::HideIME(..) => write!(f, "HideIME"), EmbedderMsg::Shutdown => write!(f, "Shutdown"), diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index 0e5d8dafd75..6926412d104 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -220,7 +220,7 @@ impl FileManagerStore { multiple_files: bool, embedder_proxy: EmbedderProxy) -> Option> { let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); - let msg = EmbedderMsg::GetSelectedFiles(patterns, multiple_files, ipc_sender); + let msg = EmbedderMsg::SelectFiles(patterns, multiple_files, ipc_sender); embedder_proxy.send(msg); match ipc_receiver.recv() { diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index 62028867c94..6d83c59153d 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -297,7 +297,7 @@ impl Browser { EmbedderMsg::GetSelectedBluetoothDevice(devices, sender) => { platform_get_selected_devices(devices, sender); }, - EmbedderMsg::GetSelectedFiles(patterns, multiple_files, sender) => { + EmbedderMsg::SelectFiles(patterns, multiple_files, sender) => { if opts::get().headless { let _ = sender.send(None); } From d94def6b4a9ba3779869edf6409d29e8817ddc42 Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Mon, 16 Apr 2018 07:52:57 -0700 Subject: [PATCH 11/11] test(net): update test cases --- components/net/tests/fetch.rs | 9 +++--- components/net/tests/filemanager_thread.rs | 5 ++- components/net/tests/http_loader.rs | 16 +++++----- components/net/tests/main.rs | 37 +++++++++++++++++++--- components/net/tests/resource_thread.rs | 10 ++---- 5 files changed, 49 insertions(+), 28 deletions(-) diff --git a/components/net/tests/fetch.rs b/components/net/tests/fetch.rs index 18607dc8cc2..1baa2d0c275 100644 --- a/components/net/tests/fetch.rs +++ b/components/net/tests/fetch.rs @@ -2,7 +2,7 @@ * 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 {DEFAULT_USER_AGENT, new_fetch_context, fetch, make_server}; +use {DEFAULT_USER_AGENT, new_fetch_context, create_embedder_proxy, fetch, make_server}; use devtools_traits::DevtoolsControlMsg; use devtools_traits::HttpRequest as DevtoolsHttpRequest; use devtools_traits::HttpResponse as DevtoolsHttpResponse; @@ -124,7 +124,7 @@ fn test_fetch_blob() { use ipc_channel::ipc; use net_traits::blob_url_store::BlobBuf; - let context = new_fetch_context(None); + let context = new_fetch_context(None, None); let bytes = b"content"; let blob_buf = BlobBuf { @@ -552,13 +552,12 @@ fn test_fetch_with_hsts() { let mut ca_content = String::new(); File::open(cert_path).unwrap().read_to_string(&mut ca_content).unwrap(); let ssl_client = create_ssl_client(&ca_content); - let (sender, _) = channel(); - let context = FetchContext { + let context = FetchContext { state: Arc::new(HttpState::new(ssl_client)), user_agent: DEFAULT_USER_AGENT.into(), devtools_chan: None, - filemanager: FileManager::new(sender), + filemanager: FileManager::new(create_embedder_proxy()), cancellation_listener: Arc::new(Mutex::new(CancellationListener::new(None))), }; diff --git a/components/net/tests/filemanager_thread.rs b/components/net/tests/filemanager_thread.rs index 557cbc0af45..d71c9f30187 100644 --- a/components/net/tests/filemanager_thread.rs +++ b/components/net/tests/filemanager_thread.rs @@ -2,6 +2,7 @@ * 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 create_embedder_proxy; use ipc_channel::ipc; use net::filemanager_thread::FileManager; use net_traits::blob_url_store::BlobURLStoreError; @@ -10,12 +11,10 @@ use servo_config::prefs::{PrefValue, PREFS}; use std::fs::File; use std::io::Read; use std::path::PathBuf; -use std::sync::mpsc::channel; #[test] fn test_filemanager() { - let (sender, _) = channel(); - let filemanager = FileManager::new(sender); + let filemanager = FileManager::new(create_embedder_proxy()); PREFS.set("dom.testing.htmlinputelement.select_files.enabled", PrefValue::Boolean(true)); // Try to open a dummy file "components/net/tests/test.jpeg" in tree diff --git a/components/net/tests/http_loader.rs b/components/net/tests/http_loader.rs index 941dda40b20..ef5bd9a0622 100644 --- a/components/net/tests/http_loader.rs +++ b/components/net/tests/http_loader.rs @@ -506,7 +506,7 @@ fn test_load_doesnt_add_host_to_sts_list_when_url_is_http_even_if_sts_headers_ar pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let context = new_fetch_context(None); + let context = new_fetch_context(None, None); let response = fetch_with_context(&mut request, &context); let _ = server.close(); @@ -523,7 +523,7 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_ }; let (mut server, url) = make_server(handler); - let context = new_fetch_context(None); + let context = new_fetch_context(None, None); assert_cookie_for_domain(&context.state.cookie_jar, url.as_str(), None); @@ -555,7 +555,7 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re }; let (mut server, url) = make_server(handler); - let context = new_fetch_context(None); + let context = new_fetch_context(None, None); { let mut cookie_jar = context.state.cookie_jar.write().unwrap(); @@ -593,7 +593,7 @@ fn test_load_sends_cookie_if_nonhttp() { }; let (mut server, url) = make_server(handler); - let context = new_fetch_context(None); + let context = new_fetch_context(None, None); { let mut cookie_jar = context.state.cookie_jar.write().unwrap(); @@ -631,7 +631,7 @@ fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl( }; let (mut server, url) = make_server(handler); - let context = new_fetch_context(None); + let context = new_fetch_context(None, None); assert_cookie_for_domain(&context.state.cookie_jar, url.as_str(), None); @@ -665,7 +665,7 @@ fn test_when_cookie_received_marked_secure_is_ignored_for_http() { }; let (mut server, url) = make_server(handler); - let context = new_fetch_context(None); + let context = new_fetch_context(None, None); assert_cookie_for_domain(&context.state.cookie_jar, url.as_str(), None); @@ -983,7 +983,7 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() { let url_y = ServoUrl::parse(&format!("http://mozilla.org:{}/org/", port)).unwrap(); *shared_url_y_clone.lock().unwrap() = Some(url_y.clone()); - let context = new_fetch_context(None); + let context = new_fetch_context(None, None); { let mut cookie_jar = context.state.cookie_jar.write().unwrap(); let cookie_x = Cookie::new_wrapped( @@ -1087,7 +1087,7 @@ fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() { credentials_mode: CredentialsMode::Include, .. RequestInit::default() }); - let context = new_fetch_context(None); + let context = new_fetch_context(None, None); let auth_entry = AuthCacheEntry { user_name: "username".to_owned(), diff --git a/components/net/tests/main.rs b/components/net/tests/main.rs index 2fe0e739923..a644a6a2fd4 100644 --- a/components/net/tests/main.rs +++ b/components/net/tests/main.rs @@ -4,6 +4,7 @@ #![cfg(test)] +extern crate compositing; extern crate cookie as cookie_rs; extern crate devtools_traits; extern crate embedder_traits; @@ -16,7 +17,6 @@ extern crate msg; extern crate net; extern crate net_traits; extern crate profile_traits; -extern crate script_traits; extern crate servo_config; extern crate servo_url; extern crate time; @@ -35,6 +35,7 @@ mod mime_classifier; mod resource_thread; mod subresource_integrity; +use compositing::compositor_thread::{EmbedderProxy, EventLoopWaker}; use devtools_traits::DevtoolsControlMsg; use embedder_traits::resources::{self, Resource}; use hyper::server::{Handler, Listening, Server}; @@ -56,9 +57,35 @@ struct FetchResponseCollector { sender: Sender, } -fn new_fetch_context(dc: Option>) -> FetchContext { - let ssl_client = create_ssl_client(&resources::read_string(Resource::SSLCertificates)); +fn create_embedder_proxy() -> EmbedderProxy { let (sender, _) = channel(); + let event_loop_waker = | | { + struct DummyEventLoopWaker { + } + impl DummyEventLoopWaker { + fn new() -> DummyEventLoopWaker { + DummyEventLoopWaker { } + } + } + impl EventLoopWaker for DummyEventLoopWaker { + fn wake(&self) { } + fn clone(&self) -> Box { + Box::new(DummyEventLoopWaker { }) + } + } + + Box::new(DummyEventLoopWaker::new()) + }; + + EmbedderProxy { + sender: sender, + event_loop_waker: event_loop_waker() + } +} + +fn new_fetch_context(dc: Option>, fc: Option) -> FetchContext { + let ssl_client = create_ssl_client(&resources::read_string(Resource::SSLCertificates)); + let sender = fc.unwrap_or_else(|| create_embedder_proxy()); FetchContext { state: Arc::new(HttpState::new(ssl_client)), user_agent: DEFAULT_USER_AGENT.into(), @@ -79,7 +106,7 @@ impl FetchTaskTarget for FetchResponseCollector { } fn fetch(request: &mut Request, dc: Option>) -> Response { - fetch_with_context(request, &new_fetch_context(dc)) + fetch_with_context(request, &new_fetch_context(dc, None)) } fn fetch_with_context(request: &mut Request, context: &FetchContext) -> Response { @@ -99,7 +126,7 @@ fn fetch_with_cors_cache(request: &mut Request, cache: &mut CorsCache) -> Respon sender: sender, }; - methods::fetch_with_cors_cache(request, cache, &mut target, &new_fetch_context(None)); + methods::fetch_with_cors_cache(request, cache, &mut target, &new_fetch_context(None, None)); receiver.recv().unwrap() } diff --git a/components/net/tests/resource_thread.rs b/components/net/tests/resource_thread.rs index 1e6c52378d9..575b67dc7de 100644 --- a/components/net/tests/resource_thread.rs +++ b/components/net/tests/resource_thread.rs @@ -2,15 +2,14 @@ * 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 create_embedder_proxy; use ipc_channel::ipc; use net::resource_thread::new_core_resource_thread; use net::test::parse_hostsfile; use net_traits::CoreResourceMsg; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan; -use script_traits::ConstellationMsg; use std::net::IpAddr; -use std::sync::mpsc::channel; fn ip(s: &str) -> IpAddr { s.parse().unwrap() @@ -20,12 +19,9 @@ fn ip(s: &str) -> IpAddr { fn test_exit() { let (tx, _rx) = ipc::channel().unwrap(); let (mtx, _mrx) = ipc::channel().unwrap(); - let (constellation, _) = channel(); let (sender, receiver) = ipc::channel().unwrap(); - let (resource_thread, _private_resource_thread, constellation_sender) = new_core_resource_thread( - "".into(), None, ProfilerChan(tx), MemProfilerChan(mtx), None); - constellation_sender.send(constellation.clone()).unwrap(); - let _ = constellation.send(ConstellationMsg::Exit); + let (resource_thread, _private_resource_thread) = new_core_resource_thread( + "".into(), None, ProfilerChan(tx), MemProfilerChan(mtx), create_embedder_proxy(), None); resource_thread.send(CoreResourceMsg::Exit(sender)).unwrap(); receiver.recv().unwrap(); }