Auto merge of #6745 - pcwalton:devtools-ipc, r=jdm

devtools: Convert the developer tools to run over IPC.

This was a large, invasive change.

r? @jdm

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6745)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-07-27 11:09:38 -06:00
commit 4bc1db3fe8
26 changed files with 295 additions and 141 deletions

View file

@ -16,12 +16,12 @@ use dom::node::{Node, NodeHelpers};
use dom::window::{WindowHelpers, ScriptHelpers};
use dom::document::DocumentHelpers;
use page::{IterablePage, Page};
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use script_task::{get_page, ScriptTask};
use js::jsapi::RootedValue;
use js::jsval::UndefinedValue;
use std::sync::mpsc::Sender;
use std::rc::Rc;
@ -29,7 +29,7 @@ pub fn handle_evaluate_js(
page: &Rc<Page>,
pipeline: PipelineId,
eval: String,
reply: Sender<EvaluateJSReply>
reply: IpcSender<EvaluateJSReply>
) {
let page = get_page(&*page, pipeline);
let window = page.window();
@ -58,7 +58,7 @@ pub fn handle_evaluate_js(
}).unwrap();
}
pub fn handle_get_root_node(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) {
pub fn handle_get_root_node(page: &Rc<Page>, pipeline: PipelineId, reply: IpcSender<NodeInfo>) {
let page = get_page(&*page, pipeline);
let document = page.document();
@ -66,7 +66,7 @@ pub fn handle_get_root_node(page: &Rc<Page>, pipeline: PipelineId, reply: Sender
reply.send(node.summarize()).unwrap();
}
pub fn handle_get_document_element(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) {
pub fn handle_get_document_element(page: &Rc<Page>, pipeline: PipelineId, reply: IpcSender<NodeInfo>) {
let page = get_page(&*page, pipeline);
let document = page.document();
let document_element = document.r().GetDocumentElement().unwrap();
@ -89,7 +89,7 @@ fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String
panic!("couldn't find node with unique id {}", node_id)
}
pub fn handle_get_children(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<Vec<NodeInfo>>) {
pub fn handle_get_children(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: IpcSender<Vec<NodeInfo>>) {
let parent = find_node_by_unique_id(&*page, pipeline, node_id);
let children = parent.r().children().map(|child| {
child.r().summarize()
@ -97,7 +97,7 @@ pub fn handle_get_children(page: &Rc<Page>, pipeline: PipelineId, node_id: Strin
reply.send(children).unwrap();
}
pub fn handle_get_layout(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<(f32, f32)>) {
pub fn handle_get_layout(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: IpcSender<(f32, f32)>) {
let node = find_node_by_unique_id(&*page, pipeline, node_id);
let elem = ElementCast::to_ref(node.r()).expect("should be getting layout of element");
let rect = elem.GetBoundingClientRect();
@ -108,7 +108,7 @@ pub fn handle_get_layout(page: &Rc<Page>, pipeline: PipelineId, node_id: String,
pub fn handle_get_cached_messages(_pipeline_id: PipelineId,
message_types: CachedConsoleMessageTypes,
reply: Sender<Vec<CachedConsoleMessage>>) {
reply: IpcSender<Vec<CachedConsoleMessage>>) {
//TODO: check the messageTypes against a global Cache for console messages and page exceptions
let mut messages = Vec::new();
if message_types.contains(PAGE_ERROR) {
@ -174,7 +174,7 @@ pub fn handle_wants_live_notifications(page: &Rc<Page>, pipeline_id: PipelineId,
pub fn handle_set_timeline_markers(page: &Rc<Page>,
script_task: &ScriptTask,
marker_types: Vec<TimelineMarkerType>,
reply: Sender<TimelineMarker>) {
reply: IpcSender<TimelineMarker>) {
for marker_type in &marker_types {
match *marker_type {
TimelineMarkerType::Reflow => {
@ -204,8 +204,10 @@ pub fn handle_drop_timeline_markers(page: &Rc<Page>,
}
}
pub fn handle_request_animation_frame(page: &Rc<Page>, id: PipelineId, callback: Box<Fn(f64, )>) {
pub fn handle_request_animation_frame(page: &Rc<Page>, id: PipelineId, callback: IpcSender<f64>) {
let page = page.find(id).expect("There is no such page");
let doc = page.document();
doc.r().request_animation_frame(callback);
doc.r().request_animation_frame(box move |time| {
callback.send(time).unwrap()
});
}

View file

@ -14,13 +14,14 @@ use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::DocumentHelpers;
use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
use dom::window::{self, WindowHelpers};
use devtools_traits::DevtoolsControlChan;
use devtools_traits::ScriptToDevtoolsControlMsg;
use script_task::{ScriptChan, ScriptPort, ScriptMsg, ScriptTask};
use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};
use net_traits::ResourceTask;
use profile_traits::mem;
use ipc_channel::ipc::IpcSender;
use js::{JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
use js::jsapi::{GetGlobalForObjectCrossCompartment};
use js::jsapi::{JSContext, JSObject};
@ -99,9 +100,9 @@ impl<'a> GlobalRef<'a> {
}
}
/// Get a `DevtoolsControlChan` to send messages to Devtools
/// Get an `IpcSender<ScriptToDevtoolsControlMsg>` to send messages to Devtools
/// task when available.
pub fn devtools_chan(&self) -> Option<DevtoolsControlChan> {
pub fn devtools_chan(&self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>> {
match *self {
GlobalRef::Window(window) => window.devtools_chan(),
GlobalRef::Worker(worker) => worker.devtools_chan(),

View file

@ -8,7 +8,7 @@ use dom::bindings::global::{GlobalRef, GlobalField};
use dom::bindings::js::Root;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::window::WindowHelpers;
use devtools_traits::{DevtoolsControlMsg, ConsoleMessage, LogLevel};
use devtools_traits::{ConsoleMessage, LogLevel, ScriptToDevtoolsControlMsg};
use util::str::DOMString;
// https://developer.mozilla.org/en-US/docs/Web/API/Console
@ -101,7 +101,7 @@ fn propagate_console_msg(console: &&Console, console_message: ConsoleMessage) {
GlobalRef::Window(window_ref) => {
let pipelineId = window_ref.pipeline();
console.global.root().r().as_window().devtools_chan().as_ref().map(|chan| {
chan.send(DevtoolsControlMsg::SendConsoleMessage(
chan.send(ScriptToDevtoolsControlMsg::SendConsoleMessage(
pipelineId, console_message.clone())).unwrap();
});
},

View file

@ -26,7 +26,7 @@ use script_task::StackRootTLS;
use msg::constellation_msg::{ConstellationChan, PipelineId};
use devtools_traits::DevtoolsControlChan;
use devtools_traits::ScriptToDevtoolsControlMsg;
use net_traits::{load_whole_resource, ResourceTask};
use profile_traits::mem::{self, Reporter, ReporterRequest};
@ -34,7 +34,7 @@ use util::task::spawn_named;
use util::task_state;
use util::task_state::{SCRIPT, IN_WORKER};
use ipc_channel::ipc;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use js::jsapi::{JSContext, RootedValue, HandleValue};
use js::jsapi::{JSAutoRequest, JSAutoCompartment};
@ -110,7 +110,7 @@ impl DedicatedWorkerGlobalScope {
fn new_inherited(worker_url: Url,
id: PipelineId,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
runtime: Rc<Runtime>,
resource_task: ResourceTask,
constellation_chan: ConstellationChan,
@ -133,7 +133,7 @@ impl DedicatedWorkerGlobalScope {
pub fn new(worker_url: Url,
id: PipelineId,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
runtime: Rc<Runtime>,
resource_task: ResourceTask,
constellation_chan: ConstellationChan,
@ -152,7 +152,7 @@ impl DedicatedWorkerGlobalScope {
pub fn run_worker_scope(worker_url: Url,
id: PipelineId,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
worker: TrustedWorkerAddress,
resource_task: ResourceTask,
constellation_chan: ConstellationChan,

View file

@ -38,7 +38,8 @@ use script_traits::ScriptControlChan;
use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
use webdriver_handlers::jsval_to_webdriver;
use devtools_traits::{DevtoolsControlChan, TimelineMarker, TimelineMarkerType, TracingMetadata};
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
use devtools_traits::{TracingMetadata};
use msg::compositor_msg::ScriptListener;
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, ConstellationChan, WindowSizeData, WorkerId};
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
@ -68,7 +69,7 @@ use std::default::Default;
use std::ffi::CString;
use std::mem as std_mem;
use std::rc::Rc;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::mpsc::{channel, Receiver};
use std::sync::mpsc::TryRecvError::{Empty, Disconnected};
use time;
@ -124,11 +125,11 @@ pub struct Window {
mem_profiler_chan: mem::ProfilerChan,
/// For providing instructions to an optional devtools server.
devtools_chan: Option<DevtoolsControlChan>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
/// For sending timeline markers. Will be ignored if
/// no devtools server
devtools_markers: RefCell<HashSet<TimelineMarkerType>>,
devtools_marker_sender: RefCell<Option<Sender<TimelineMarker>>>,
devtools_marker_sender: RefCell<Option<IpcSender<TimelineMarker>>>,
/// A flag to indicate whether the developer tools have requested live updates of
/// page changes.
@ -547,7 +548,7 @@ pub trait WindowHelpers {
fn get_url(self) -> Url;
fn resource_task(self) -> ResourceTask;
fn mem_profiler_chan(self) -> mem::ProfilerChan;
fn devtools_chan(self) -> Option<DevtoolsControlChan>;
fn devtools_chan(self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>>;
fn layout_chan(self) -> LayoutChan;
fn constellation_chan(self) -> ConstellationChan;
fn windowproxy_handler(self) -> WindowProxyHandler;
@ -564,7 +565,9 @@ pub trait WindowHelpers {
fn freeze(self);
fn need_emit_timeline_marker(self, timeline_type: TimelineMarkerType) -> bool;
fn emit_timeline_marker(self, marker: TimelineMarker);
fn set_devtools_timeline_marker(self, marker: TimelineMarkerType, reply: Sender<TimelineMarker>);
fn set_devtools_timeline_marker(self,
marker: TimelineMarkerType,
reply: IpcSender<TimelineMarker>);
fn drop_devtools_timeline_markers(self);
fn set_webdriver_script_chan(self, chan: Option<IpcSender<WebDriverJSResult>>);
fn is_alive(self) -> bool;
@ -832,7 +835,7 @@ impl<'a> WindowHelpers for &'a Window {
self.mem_profiler_chan.clone()
}
fn devtools_chan(self) -> Option<DevtoolsControlChan> {
fn devtools_chan(self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>> {
self.devtools_chan.clone()
}
@ -935,7 +938,9 @@ impl<'a> WindowHelpers for &'a Window {
sender.send(marker).unwrap();
}
fn set_devtools_timeline_marker(self, marker: TimelineMarkerType, reply: Sender<TimelineMarker>) {
fn set_devtools_timeline_marker(self,
marker: TimelineMarkerType,
reply: IpcSender<TimelineMarker>) {
*self.devtools_marker_sender.borrow_mut() = Some(reply);
self.devtools_markers.borrow_mut().insert(marker);
}
@ -978,7 +983,7 @@ impl Window {
resource_task: ResourceTask,
storage_task: StorageTask,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
constellation_chan: ConstellationChan,
layout_chan: LayoutChan,
id: PipelineId,

View file

@ -22,10 +22,11 @@ use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
use dom::messageevent::MessageEvent;
use script_task::{ScriptChan, ScriptMsg, Runnable};
use devtools_traits::{DevtoolsControlMsg, DevtoolsPageInfo};
use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg};
use util::str::DOMString;
use ipc_channel::ipc;
use js::jsapi::{JSContext, HandleValue, RootedValue};
use js::jsapi::{JSAutoRequest, JSAutoCompartment};
use js::jsval::UndefinedValue;
@ -78,16 +79,16 @@ impl Worker {
if let Some(ref chan) = global.devtools_chan() {
let pipeline_id = global.pipeline();
let (devtools_sender, _) = channel();
let (devtools_sender, _) = ipc::channel().unwrap();
let title = format!("Worker for {}", worker_url);
let page_info = DevtoolsPageInfo {
title: title,
url: worker_url.clone(),
};
let worker_id = global.get_next_worker_id();
chan.send(
DevtoolsControlMsg::NewGlobal((pipeline_id, Some(worker_id)), devtools_sender.clone(), page_info)
).unwrap();
chan.send(ScriptToDevtoolsControlMsg::NewGlobal((pipeline_id, Some(worker_id)),
devtools_sender.clone(),
page_info)).unwrap();
}
DedicatedWorkerGlobalScope::run_worker_scope(

View file

@ -20,13 +20,14 @@ use dom::window::{base64_atob, base64_btoa};
use script_task::{ScriptChan, TimerSource, ScriptPort, ScriptMsg};
use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
use devtools_traits::DevtoolsControlChan;
use devtools_traits::ScriptToDevtoolsControlMsg;
use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};
use profile_traits::mem;
use net_traits::{load_whole_resource, ResourceTask};
use util::str::DOMString;
use ipc_channel::ipc::IpcSender;
use js::jsapi::{JSContext, HandleValue};
use js::rust::Runtime;
use url::{Url, UrlParser};
@ -54,7 +55,7 @@ pub struct WorkerGlobalScope {
crypto: MutNullableHeap<JS<Crypto>>,
timers: TimerManager,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
constellation_chan: ConstellationChan,
}
@ -64,8 +65,9 @@ impl WorkerGlobalScope {
runtime: Rc<Runtime>,
resource_task: ResourceTask,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>,
constellation_chan: ConstellationChan) -> WorkerGlobalScope {
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
constellation_chan: ConstellationChan)
-> WorkerGlobalScope {
WorkerGlobalScope {
eventtarget: EventTarget::new_inherited(EventTargetTypeId::WorkerGlobalScope(type_id)),
next_worker_id: Cell::new(WorkerId(0)),
@ -87,7 +89,7 @@ impl WorkerGlobalScope {
self.mem_profiler_chan.clone()
}
pub fn devtools_chan(&self) -> Option<DevtoolsControlChan> {
pub fn devtools_chan(&self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>> {
self.devtools_chan.clone()
}

View file

@ -50,9 +50,9 @@ use timers::TimerId;
use devtools;
use webdriver_handlers;
use devtools_traits::{DevtoolsControlChan, DevtoolsControlPort, DevtoolsPageInfo};
use devtools_traits::{DevtoolsControlMsg, DevtoolScriptControlMsg};
use devtools_traits::{TimelineMarker, TimelineMarkerType, TracingMetadata};
use devtools_traits::{DevtoolsControlPort, DevtoolsPageInfo, DevtoolScriptControlMsg};
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
use devtools_traits::{TracingMetadata};
use script_traits::CompositorEvent::{MouseDownEvent, MouseUpEvent};
use script_traits::CompositorEvent::{MouseMoveEvent, KeyEvent};
use script_traits::CompositorEvent::{ResizeEvent, ClickEvent};
@ -79,7 +79,7 @@ use util::task_state;
use euclid::Rect;
use euclid::point::Point2D;
use hyper::header::{LastModified, Headers};
use ipc_channel::ipc;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use js::glue::CollectServoSizes;
use js::jsapi::{JS_SetWrapObjectCallbacks, JS_AddExtraGCRootsTracer, DisableIncrementalGC};
@ -320,15 +320,15 @@ pub struct ScriptTask {
mem_profiler_chan: mem::ProfilerChan,
/// For providing instructions to an optional devtools server.
devtools_chan: Option<DevtoolsControlChan>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
/// For receiving commands from an optional devtools server. Will be ignored if
/// no such server exists.
devtools_port: DevtoolsControlPort,
devtools_sender: Sender<DevtoolScriptControlMsg>,
devtools_sender: IpcSender<DevtoolScriptControlMsg>,
/// For sending timeline markers. Will be ignored if
/// no devtools server
devtools_markers: RefCell<HashSet<TimelineMarkerType>>,
devtools_marker_sender: RefCell<Option<Sender<TimelineMarker>>>,
devtools_marker_sender: RefCell<Option<IpcSender<TimelineMarker>>>,
/// The JavaScript runtime.
js_runtime: Rc<Runtime>,
@ -400,7 +400,7 @@ impl ScriptTaskFactory for ScriptTask {
storage_task: StorageTask,
image_cache_task: ImageCacheTask,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
window_size: Option<WindowSizeData>,
load_data: LoadData) {
let ConstellationChan(const_chan) = constellation_chan.clone();
@ -507,7 +507,7 @@ impl ScriptTask {
storage_task: StorageTask,
image_cache_task: ImageCacheTask,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>)
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>)
-> ScriptTask {
let runtime = ScriptTask::new_rt_and_cx();
@ -516,7 +516,9 @@ impl ScriptTask {
&WRAP_CALLBACKS);
}
let (devtools_sender, devtools_receiver) = channel();
// Ask the router to proxy IPC messages from the devtools to us.
let (ipc_devtools_sender, ipc_devtools_receiver) = ipc::channel().unwrap();
let devtools_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_devtools_receiver);
// Ask the router to proxy IPC messages from the image cache task to us.
let (ipc_image_cache_channel, ipc_image_cache_port) = ipc::channel().unwrap();
@ -543,8 +545,8 @@ impl ScriptTask {
mem_profiler_chan: mem_profiler_chan,
devtools_chan: devtools_chan,
devtools_port: devtools_receiver,
devtools_sender: devtools_sender,
devtools_port: devtools_port,
devtools_sender: ipc_devtools_sender,
devtools_markers: RefCell::new(HashSet::new()),
devtools_marker_sender: RefCell::new(None),
@ -1435,9 +1437,10 @@ impl ScriptTask {
title: title,
url: url,
};
chan.send(DevtoolsControlMsg::NewGlobal(ids,
self.devtools_sender.clone(),
page_info)).unwrap();
chan.send(ScriptToDevtoolsControlMsg::NewGlobal(
ids,
self.devtools_sender.clone(),
page_info)).unwrap();
}
}
}
@ -1637,7 +1640,9 @@ impl ScriptTask {
sender.send(marker).unwrap();
}
pub fn set_devtools_timeline_marker(&self, marker: TimelineMarkerType, reply: Sender<TimelineMarker>) {
pub fn set_devtools_timeline_marker(&self,
marker: TimelineMarkerType,
reply: IpcSender<TimelineMarker>) {
*self.devtools_marker_sender.borrow_mut() = Some(reply);
self.devtools_markers.borrow_mut().insert(marker);
}