mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Support connecting to worker globals from remote devtools.
This commit is contained in:
parent
bce4ec5b70
commit
565e9432c6
13 changed files with 340 additions and 144 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1189,6 +1189,7 @@ dependencies = [
|
||||||
"msg",
|
"msg",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"servo_url",
|
||||||
"time",
|
"time",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
|
@ -22,5 +22,6 @@ log = "0.4"
|
||||||
msg = {path = "../msg"}
|
msg = {path = "../msg"}
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
servo_url = { path = "../url" }
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
uuid = {version = "0.8", features = ["v4"]}
|
uuid = {version = "0.8", features = ["v4"]}
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
|
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
|
||||||
use crate::actors::browsing_context::BrowsingContextActor;
|
use crate::actors::browsing_context::BrowsingContextActor;
|
||||||
use crate::actors::object::ObjectActor;
|
use crate::actors::object::ObjectActor;
|
||||||
|
use crate::actors::worker::WorkerActor;
|
||||||
use crate::protocol::JsonPacketStream;
|
use crate::protocol::JsonPacketStream;
|
||||||
|
use crate::UniqueId;
|
||||||
use crate::{ConsoleAPICall, ConsoleMessage, ConsoleMsg, PageErrorMsg};
|
use crate::{ConsoleAPICall, ConsoleMessage, ConsoleMsg, PageErrorMsg};
|
||||||
use devtools_traits::CachedConsoleMessage;
|
use devtools_traits::CachedConsoleMessage;
|
||||||
use devtools_traits::EvaluateJSReply::{ActorValue, BooleanValue, StringValue};
|
use devtools_traits::EvaluateJSReply::{ActorValue, BooleanValue, StringValue};
|
||||||
|
@ -18,10 +20,10 @@ use devtools_traits::EvaluateJSReply::{NullValue, NumberValue, VoidValue};
|
||||||
use devtools_traits::{
|
use devtools_traits::{
|
||||||
CachedConsoleMessageTypes, ConsoleAPI, DevtoolScriptControlMsg, LogLevel, PageError,
|
CachedConsoleMessageTypes, ConsoleAPI, DevtoolScriptControlMsg, LogLevel, PageError,
|
||||||
};
|
};
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::TEST_PIPELINE_ID;
|
||||||
use serde_json::{self, Map, Number, Value};
|
use serde_json::{self, Map, Number, Value};
|
||||||
use std::cell::RefCell;
|
use std::cell::{RefCell, RefMut};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use time::precise_time_ns;
|
use time::precise_time_ns;
|
||||||
|
@ -106,25 +108,68 @@ struct SetPreferencesReply {
|
||||||
updated: Vec<String>,
|
updated: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ConsoleActor {
|
pub(crate) enum Root {
|
||||||
|
BrowsingContext(String),
|
||||||
|
DedicatedWorker(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct ConsoleActor {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub browsing_context: String,
|
pub root: Root,
|
||||||
pub cached_events: RefCell<HashMap<PipelineId, Vec<CachedConsoleMessage>>>,
|
pub cached_events: RefCell<HashMap<UniqueId, Vec<CachedConsoleMessage>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConsoleActor {
|
impl ConsoleActor {
|
||||||
|
fn script_chan<'a>(
|
||||||
|
&self,
|
||||||
|
registry: &'a ActorRegistry,
|
||||||
|
) -> &'a IpcSender<DevtoolScriptControlMsg> {
|
||||||
|
match &self.root {
|
||||||
|
Root::BrowsingContext(bc) => ®istry.find::<BrowsingContextActor>(bc).script_chan,
|
||||||
|
Root::DedicatedWorker(worker) => ®istry.find::<WorkerActor>(worker).script_chan,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn streams_mut<'a>(&self, registry: &'a ActorRegistry) -> RefMut<'a, Vec<TcpStream>> {
|
||||||
|
match &self.root {
|
||||||
|
Root::BrowsingContext(bc) => registry
|
||||||
|
.find::<BrowsingContextActor>(bc)
|
||||||
|
.streams
|
||||||
|
.borrow_mut(),
|
||||||
|
Root::DedicatedWorker(worker) => {
|
||||||
|
registry.find::<WorkerActor>(worker).streams.borrow_mut()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_unique_id(&self, registry: &ActorRegistry) -> UniqueId {
|
||||||
|
match &self.root {
|
||||||
|
Root::BrowsingContext(bc) => UniqueId::Pipeline(
|
||||||
|
registry
|
||||||
|
.find::<BrowsingContextActor>(bc)
|
||||||
|
.active_pipeline
|
||||||
|
.get(),
|
||||||
|
),
|
||||||
|
Root::DedicatedWorker(w) => UniqueId::Worker(registry.find::<WorkerActor>(w).id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn evaluateJS(
|
fn evaluateJS(
|
||||||
&self,
|
&self,
|
||||||
registry: &ActorRegistry,
|
registry: &ActorRegistry,
|
||||||
msg: &Map<String, Value>,
|
msg: &Map<String, Value>,
|
||||||
) -> Result<EvaluateJSReply, ()> {
|
) -> Result<EvaluateJSReply, ()> {
|
||||||
let browsing_context = registry.find::<BrowsingContextActor>(&self.browsing_context);
|
|
||||||
let input = msg.get("text").unwrap().as_str().unwrap().to_owned();
|
let input = msg.get("text").unwrap().as_str().unwrap().to_owned();
|
||||||
let (chan, port) = ipc::channel().unwrap();
|
let (chan, port) = ipc::channel().unwrap();
|
||||||
browsing_context
|
// FIXME: redesign messages so we don't have to fake pipeline ids when
|
||||||
.script_chan
|
// communicating with workers.
|
||||||
|
let pipeline = match self.current_unique_id(registry) {
|
||||||
|
UniqueId::Pipeline(p) => p,
|
||||||
|
UniqueId::Worker(_) => TEST_PIPELINE_ID,
|
||||||
|
};
|
||||||
|
self.script_chan(registry)
|
||||||
.send(DevtoolScriptControlMsg::EvaluateJS(
|
.send(DevtoolScriptControlMsg::EvaluateJS(
|
||||||
browsing_context.active_pipeline.get(),
|
pipeline,
|
||||||
input.clone(),
|
input.clone(),
|
||||||
chan,
|
chan,
|
||||||
))
|
))
|
||||||
|
@ -196,21 +241,21 @@ impl ConsoleActor {
|
||||||
pub(crate) fn handle_page_error(
|
pub(crate) fn handle_page_error(
|
||||||
&self,
|
&self,
|
||||||
page_error: PageError,
|
page_error: PageError,
|
||||||
pipeline: PipelineId,
|
id: UniqueId,
|
||||||
browsing_context: &BrowsingContextActor,
|
registry: &ActorRegistry,
|
||||||
) {
|
) {
|
||||||
self.cached_events
|
self.cached_events
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.entry(pipeline)
|
.entry(id.clone())
|
||||||
.or_insert(vec![])
|
.or_insert(vec![])
|
||||||
.push(CachedConsoleMessage::PageError(page_error.clone()));
|
.push(CachedConsoleMessage::PageError(page_error.clone()));
|
||||||
if browsing_context.active_pipeline.get() == pipeline {
|
if id == self.current_unique_id(registry) {
|
||||||
let msg = PageErrorMsg {
|
let msg = PageErrorMsg {
|
||||||
from: self.name(),
|
from: self.name(),
|
||||||
type_: "pageError".to_owned(),
|
type_: "pageError".to_owned(),
|
||||||
pageError: page_error,
|
pageError: page_error,
|
||||||
};
|
};
|
||||||
for stream in &mut *browsing_context.streams.borrow_mut() {
|
for stream in &mut *self.streams_mut(registry) {
|
||||||
stream.write_json_packet(&msg);
|
stream.write_json_packet(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,8 +264,8 @@ impl ConsoleActor {
|
||||||
pub(crate) fn handle_console_api(
|
pub(crate) fn handle_console_api(
|
||||||
&self,
|
&self,
|
||||||
console_message: ConsoleMessage,
|
console_message: ConsoleMessage,
|
||||||
pipeline: PipelineId,
|
id: UniqueId,
|
||||||
browsing_context: &BrowsingContextActor,
|
registry: &ActorRegistry,
|
||||||
) {
|
) {
|
||||||
let level = match console_message.logLevel {
|
let level = match console_message.logLevel {
|
||||||
LogLevel::Debug => "debug",
|
LogLevel::Debug => "debug",
|
||||||
|
@ -232,7 +277,7 @@ impl ConsoleActor {
|
||||||
.to_owned();
|
.to_owned();
|
||||||
self.cached_events
|
self.cached_events
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.entry(pipeline)
|
.entry(id.clone())
|
||||||
.or_insert(vec![])
|
.or_insert(vec![])
|
||||||
.push(CachedConsoleMessage::ConsoleAPI(ConsoleAPI {
|
.push(CachedConsoleMessage::ConsoleAPI(ConsoleAPI {
|
||||||
type_: "ConsoleAPI".to_owned(),
|
type_: "ConsoleAPI".to_owned(),
|
||||||
|
@ -244,7 +289,7 @@ impl ConsoleActor {
|
||||||
private: false,
|
private: false,
|
||||||
arguments: vec![console_message.message.clone()],
|
arguments: vec![console_message.message.clone()],
|
||||||
}));
|
}));
|
||||||
if browsing_context.active_pipeline.get() == pipeline {
|
if id == self.current_unique_id(registry) {
|
||||||
let msg = ConsoleAPICall {
|
let msg = ConsoleAPICall {
|
||||||
from: self.name(),
|
from: self.name(),
|
||||||
type_: "consoleAPICall".to_owned(),
|
type_: "consoleAPICall".to_owned(),
|
||||||
|
@ -257,7 +302,7 @@ impl ConsoleActor {
|
||||||
columnNumber: console_message.columnNumber,
|
columnNumber: console_message.columnNumber,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
for stream in &mut *browsing_context.streams.borrow_mut() {
|
for stream in &mut *self.streams_mut(registry) {
|
||||||
stream.write_json_packet(&msg);
|
stream.write_json_packet(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,11 +323,11 @@ impl Actor for ConsoleActor {
|
||||||
) -> Result<ActorMessageStatus, ()> {
|
) -> Result<ActorMessageStatus, ()> {
|
||||||
Ok(match msg_type {
|
Ok(match msg_type {
|
||||||
"clearMessagesCache" => {
|
"clearMessagesCache" => {
|
||||||
let browsing_context =
|
self.cached_events
|
||||||
registry.find::<BrowsingContextActor>(&self.browsing_context);
|
.borrow_mut()
|
||||||
self.cached_events.borrow_mut().remove(&browsing_context.active_pipeline.get());
|
.remove(&self.current_unique_id(registry));
|
||||||
ActorMessageStatus::Processed
|
ActorMessageStatus::Processed
|
||||||
}
|
},
|
||||||
|
|
||||||
"getCachedMessages" => {
|
"getCachedMessages" => {
|
||||||
let str_types = msg
|
let str_types = msg
|
||||||
|
@ -302,13 +347,11 @@ impl Actor for ConsoleActor {
|
||||||
s => debug!("unrecognized message type requested: \"{}\"", s),
|
s => debug!("unrecognized message type requested: \"{}\"", s),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let browsing_context =
|
|
||||||
registry.find::<BrowsingContextActor>(&self.browsing_context);
|
|
||||||
let mut messages = vec![];
|
let mut messages = vec![];
|
||||||
for event in self
|
for event in self
|
||||||
.cached_events
|
.cached_events
|
||||||
.borrow()
|
.borrow()
|
||||||
.get(&browsing_context.active_pipeline.get())
|
.get(&self.current_unique_id(registry))
|
||||||
.unwrap_or(&vec![])
|
.unwrap_or(&vec![])
|
||||||
.iter()
|
.iter()
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@ use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
|
||||||
use crate::actors::browsing_context::{BrowsingContextActor, BrowsingContextActorMsg};
|
use crate::actors::browsing_context::{BrowsingContextActor, BrowsingContextActorMsg};
|
||||||
use crate::actors::device::DeviceActor;
|
use crate::actors::device::DeviceActor;
|
||||||
use crate::actors::performance::PerformanceActor;
|
use crate::actors::performance::PerformanceActor;
|
||||||
|
use crate::actors::worker::{WorkerActor, WorkerMsg};
|
||||||
use crate::protocol::{ActorDescription, JsonPacketStream};
|
use crate::protocol::{ActorDescription, JsonPacketStream};
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
|
@ -72,11 +73,6 @@ struct ListWorkersReply {
|
||||||
workers: Vec<WorkerMsg>,
|
workers: Vec<WorkerMsg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
struct WorkerMsg {
|
|
||||||
id: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct ListServiceWorkerRegistrationsReply {
|
struct ListServiceWorkerRegistrationsReply {
|
||||||
from: String,
|
from: String,
|
||||||
|
@ -110,6 +106,7 @@ struct GetProcessResponse {
|
||||||
|
|
||||||
pub struct RootActor {
|
pub struct RootActor {
|
||||||
pub tabs: Vec<String>,
|
pub tabs: Vec<String>,
|
||||||
|
pub workers: Vec<String>,
|
||||||
pub performance: String,
|
pub performance: String,
|
||||||
pub device: String,
|
pub device: String,
|
||||||
pub preference: String,
|
pub preference: String,
|
||||||
|
@ -203,7 +200,11 @@ impl Actor for RootActor {
|
||||||
"listWorkers" => {
|
"listWorkers" => {
|
||||||
let reply = ListWorkersReply {
|
let reply = ListWorkersReply {
|
||||||
from: self.name(),
|
from: self.name(),
|
||||||
workers: vec![],
|
workers: self
|
||||||
|
.workers
|
||||||
|
.iter()
|
||||||
|
.map(|name| registry.find::<WorkerActor>(name).encodable())
|
||||||
|
.collect(),
|
||||||
};
|
};
|
||||||
stream.write_json_packet(&reply);
|
stream.write_json_packet(&reply);
|
||||||
ActorMessageStatus::Processed
|
ActorMessageStatus::Processed
|
||||||
|
|
|
@ -3,14 +3,49 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
|
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
|
||||||
use devtools_traits::WorkerId;
|
use crate::protocol::JsonPacketStream;
|
||||||
|
use devtools_traits::DevtoolScriptControlMsg::WantsLiveNotifications;
|
||||||
|
use devtools_traits::{DevtoolScriptControlMsg, WorkerId};
|
||||||
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
use msg::constellation_msg::TEST_PIPELINE_ID;
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
|
use servo_url::ServoUrl;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub enum WorkerType {
|
||||||
|
Dedicated = 0,
|
||||||
|
Shared = 1,
|
||||||
|
Service = 2,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WorkerActor {
|
pub struct WorkerActor {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub console: String,
|
pub console: String,
|
||||||
|
pub thread: String,
|
||||||
pub id: WorkerId,
|
pub id: WorkerId,
|
||||||
|
pub url: ServoUrl,
|
||||||
|
pub type_: WorkerType,
|
||||||
|
pub script_chan: IpcSender<DevtoolScriptControlMsg>,
|
||||||
|
pub streams: RefCell<Vec<TcpStream>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WorkerActor {
|
||||||
|
pub(crate) fn encodable(&self) -> WorkerMsg {
|
||||||
|
WorkerMsg {
|
||||||
|
actor: self.name.clone(),
|
||||||
|
consoleActor: self.console.clone(),
|
||||||
|
threadActor: self.thread.clone(),
|
||||||
|
id: self.id.0.to_string(),
|
||||||
|
url: self.url.to_string(),
|
||||||
|
traits: WorkerTraits {
|
||||||
|
isParentInterceptEnabled: false,
|
||||||
|
},
|
||||||
|
type_: self.type_ as u32,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Actor for WorkerActor {
|
impl Actor for WorkerActor {
|
||||||
|
@ -19,11 +54,94 @@ impl Actor for WorkerActor {
|
||||||
}
|
}
|
||||||
fn handle_message(
|
fn handle_message(
|
||||||
&self,
|
&self,
|
||||||
_: &ActorRegistry,
|
_registry: &ActorRegistry,
|
||||||
_: &str,
|
msg_type: &str,
|
||||||
_: &Map<String, Value>,
|
_msg: &Map<String, Value>,
|
||||||
_: &mut TcpStream,
|
stream: &mut TcpStream,
|
||||||
) -> Result<ActorMessageStatus, ()> {
|
) -> Result<ActorMessageStatus, ()> {
|
||||||
Ok(ActorMessageStatus::Processed)
|
Ok(match msg_type {
|
||||||
|
"attach" => {
|
||||||
|
let msg = AttachedReply {
|
||||||
|
from: self.name(),
|
||||||
|
type_: "attached".to_owned(),
|
||||||
|
url: self.url.as_str().to_owned(),
|
||||||
|
};
|
||||||
|
self.streams.borrow_mut().push(stream.try_clone().unwrap());
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
// FIXME: fix messages to not require forging a pipeline for worker messages
|
||||||
|
self.script_chan
|
||||||
|
.send(WantsLiveNotifications(TEST_PIPELINE_ID, true))
|
||||||
|
.unwrap();
|
||||||
|
ActorMessageStatus::Processed
|
||||||
|
},
|
||||||
|
|
||||||
|
"connect" => {
|
||||||
|
let msg = ConnectReply {
|
||||||
|
from: self.name(),
|
||||||
|
type_: "connected".to_owned(),
|
||||||
|
threadActor: self.thread.clone(),
|
||||||
|
consoleActor: self.console.clone(),
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
ActorMessageStatus::Processed
|
||||||
|
},
|
||||||
|
|
||||||
|
"detach" => {
|
||||||
|
let msg = DetachedReply {
|
||||||
|
from: self.name(),
|
||||||
|
type_: "detached".to_string(),
|
||||||
|
};
|
||||||
|
// FIXME: we should ensure we're removing the correct stream.
|
||||||
|
self.streams.borrow_mut().pop();
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
self.script_chan
|
||||||
|
.send(WantsLiveNotifications(TEST_PIPELINE_ID, false))
|
||||||
|
.unwrap();
|
||||||
|
ActorMessageStatus::Processed
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => ActorMessageStatus::Ignored,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct DetachedReply {
|
||||||
|
from: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
type_: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct AttachedReply {
|
||||||
|
from: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
type_: String,
|
||||||
|
url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct ConnectReply {
|
||||||
|
from: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
type_: String,
|
||||||
|
threadActor: String,
|
||||||
|
consoleActor: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct WorkerTraits {
|
||||||
|
isParentInterceptEnabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub(crate) struct WorkerMsg {
|
||||||
|
actor: String,
|
||||||
|
consoleActor: String,
|
||||||
|
threadActor: String,
|
||||||
|
id: String,
|
||||||
|
url: String,
|
||||||
|
traits: WorkerTraits,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
type_: u32,
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ extern crate serde;
|
||||||
|
|
||||||
use crate::actor::{Actor, ActorRegistry};
|
use crate::actor::{Actor, ActorRegistry};
|
||||||
use crate::actors::browsing_context::BrowsingContextActor;
|
use crate::actors::browsing_context::BrowsingContextActor;
|
||||||
use crate::actors::console::ConsoleActor;
|
use crate::actors::console::{ConsoleActor, Root};
|
||||||
use crate::actors::device::DeviceActor;
|
use crate::actors::device::DeviceActor;
|
||||||
use crate::actors::framerate::FramerateActor;
|
use crate::actors::framerate::FramerateActor;
|
||||||
use crate::actors::network_event::{EventActor, NetworkEventActor, ResponseStartMsg};
|
use crate::actors::network_event::{EventActor, NetworkEventActor, ResponseStartMsg};
|
||||||
|
@ -27,7 +27,8 @@ use crate::actors::performance::PerformanceActor;
|
||||||
use crate::actors::preference::PreferenceActor;
|
use crate::actors::preference::PreferenceActor;
|
||||||
use crate::actors::process::ProcessActor;
|
use crate::actors::process::ProcessActor;
|
||||||
use crate::actors::root::RootActor;
|
use crate::actors::root::RootActor;
|
||||||
use crate::actors::worker::WorkerActor;
|
use crate::actors::thread::ThreadActor;
|
||||||
|
use crate::actors::worker::{WorkerActor, WorkerType};
|
||||||
use crate::protocol::JsonPacketStream;
|
use crate::protocol::JsonPacketStream;
|
||||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||||
use devtools_traits::{ChromeToDevtoolsControlMsg, ConsoleMessage, DevtoolsControlMsg};
|
use devtools_traits::{ChromeToDevtoolsControlMsg, ConsoleMessage, DevtoolsControlMsg};
|
||||||
|
@ -69,6 +70,12 @@ mod actors {
|
||||||
}
|
}
|
||||||
mod protocol;
|
mod protocol;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||||
|
enum UniqueId {
|
||||||
|
Pipeline(PipelineId),
|
||||||
|
Worker(WorkerId),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct ConsoleAPICall {
|
struct ConsoleAPICall {
|
||||||
from: String,
|
from: String,
|
||||||
|
@ -176,6 +183,7 @@ fn run_server(
|
||||||
|
|
||||||
let root = Box::new(RootActor {
|
let root = Box::new(RootActor {
|
||||||
tabs: vec![],
|
tabs: vec![],
|
||||||
|
workers: vec![],
|
||||||
device: device.name(),
|
device: device.name(),
|
||||||
performance: performance.name(),
|
performance: performance.name(),
|
||||||
preference: preference.name(),
|
preference: preference.name(),
|
||||||
|
@ -197,7 +205,7 @@ fn run_server(
|
||||||
let mut pipelines: HashMap<PipelineId, BrowsingContextId> = HashMap::new();
|
let mut pipelines: HashMap<PipelineId, BrowsingContextId> = HashMap::new();
|
||||||
let mut actor_requests: HashMap<String, String> = HashMap::new();
|
let mut actor_requests: HashMap<String, String> = HashMap::new();
|
||||||
|
|
||||||
let mut actor_workers: HashMap<(PipelineId, WorkerId), String> = HashMap::new();
|
let mut actor_workers: HashMap<WorkerId, String> = HashMap::new();
|
||||||
|
|
||||||
/// Process the input from a single devtools client until EOF.
|
/// Process the input from a single devtools client until EOF.
|
||||||
fn handle_client(actors: Arc<Mutex<ActorRegistry>>, mut stream: TcpStream) {
|
fn handle_client(actors: Arc<Mutex<ActorRegistry>>, mut stream: TcpStream) {
|
||||||
|
@ -258,11 +266,11 @@ fn run_server(
|
||||||
// TODO: move this into the root or target modules?
|
// TODO: move this into the root or target modules?
|
||||||
fn handle_new_global(
|
fn handle_new_global(
|
||||||
actors: Arc<Mutex<ActorRegistry>>,
|
actors: Arc<Mutex<ActorRegistry>>,
|
||||||
ids: (Option<BrowsingContextId>, PipelineId, Option<WorkerId>),
|
ids: (BrowsingContextId, PipelineId, Option<WorkerId>),
|
||||||
script_sender: IpcSender<DevtoolScriptControlMsg>,
|
script_sender: IpcSender<DevtoolScriptControlMsg>,
|
||||||
browsing_contexts: &mut HashMap<BrowsingContextId, String>,
|
browsing_contexts: &mut HashMap<BrowsingContextId, String>,
|
||||||
pipelines: &mut HashMap<PipelineId, BrowsingContextId>,
|
pipelines: &mut HashMap<PipelineId, BrowsingContextId>,
|
||||||
actor_workers: &mut HashMap<(PipelineId, WorkerId), String>,
|
actor_workers: &mut HashMap<WorkerId, String>,
|
||||||
page_info: DevtoolsPageInfo,
|
page_info: DevtoolsPageInfo,
|
||||||
) {
|
) {
|
||||||
let mut actors = actors.lock().unwrap();
|
let mut actors = actors.lock().unwrap();
|
||||||
|
@ -271,83 +279,70 @@ fn run_server(
|
||||||
|
|
||||||
let console_name = actors.new_name("console");
|
let console_name = actors.new_name("console");
|
||||||
|
|
||||||
let browsing_context_name = if let Some(browsing_context) = browsing_context {
|
let parent_actor = if let Some(id) = worker_id {
|
||||||
pipelines.insert(pipeline, browsing_context);
|
assert!(pipelines.get(&pipeline).is_some());
|
||||||
if let Some(actor) = browsing_contexts.get(&browsing_context) {
|
assert!(browsing_contexts.get(&browsing_context).is_some());
|
||||||
actor.to_owned()
|
|
||||||
} else {
|
let thread = ThreadActor::new(actors.new_name("context"));
|
||||||
let browsing_context_actor = BrowsingContextActor::new(
|
let thread_name = thread.name();
|
||||||
console_name.clone(),
|
actors.register(Box::new(thread));
|
||||||
browsing_context,
|
|
||||||
page_info,
|
let worker_name = actors.new_name("worker");
|
||||||
pipeline,
|
let worker = WorkerActor {
|
||||||
script_sender.clone(),
|
name: worker_name.clone(),
|
||||||
&mut *actors,
|
console: console_name.clone(),
|
||||||
);
|
thread: thread_name,
|
||||||
let name = browsing_context_actor.name();
|
id: id,
|
||||||
browsing_contexts.insert(browsing_context, name.clone());
|
url: page_info.url.clone(),
|
||||||
actors.register(Box::new(browsing_context_actor));
|
type_: WorkerType::Dedicated,
|
||||||
name
|
script_chan: script_sender,
|
||||||
}
|
streams: Default::default(),
|
||||||
|
};
|
||||||
|
let root = actors.find_mut::<RootActor>("root");
|
||||||
|
root.workers.push(worker.name.clone());
|
||||||
|
|
||||||
|
actor_workers.insert(id, worker_name.clone());
|
||||||
|
actors.register(Box::new(worker));
|
||||||
|
|
||||||
|
Root::DedicatedWorker(worker_name)
|
||||||
} else {
|
} else {
|
||||||
"".to_owned()
|
pipelines.insert(pipeline, browsing_context);
|
||||||
|
Root::BrowsingContext(
|
||||||
|
if let Some(actor) = browsing_contexts.get(&browsing_context) {
|
||||||
|
actor.to_owned()
|
||||||
|
} else {
|
||||||
|
let browsing_context_actor = BrowsingContextActor::new(
|
||||||
|
console_name.clone(),
|
||||||
|
browsing_context,
|
||||||
|
page_info,
|
||||||
|
pipeline,
|
||||||
|
script_sender,
|
||||||
|
&mut *actors,
|
||||||
|
);
|
||||||
|
let name = browsing_context_actor.name();
|
||||||
|
browsing_contexts.insert(browsing_context, name.clone());
|
||||||
|
actors.register(Box::new(browsing_context_actor));
|
||||||
|
name
|
||||||
|
},
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
// XXXjdm this new actor is useless if it's not a new worker global
|
|
||||||
let console = ConsoleActor {
|
let console = ConsoleActor {
|
||||||
name: console_name,
|
name: console_name,
|
||||||
cached_events: Default::default(),
|
cached_events: Default::default(),
|
||||||
browsing_context: browsing_context_name,
|
root: parent_actor,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(id) = worker_id {
|
|
||||||
let worker = WorkerActor {
|
|
||||||
name: actors.new_name("worker"),
|
|
||||||
console: console.name(),
|
|
||||||
id: id,
|
|
||||||
};
|
|
||||||
let root = actors.find_mut::<RootActor>("root");
|
|
||||||
root.tabs.push(worker.name.clone());
|
|
||||||
|
|
||||||
actor_workers.insert((pipeline, id), worker.name.clone());
|
|
||||||
actors.register(Box::new(worker));
|
|
||||||
}
|
|
||||||
|
|
||||||
actors.register(Box::new(console));
|
actors.register(Box::new(console));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_page_error(
|
fn handle_page_error(
|
||||||
actors: Arc<Mutex<ActorRegistry>>,
|
actors: Arc<Mutex<ActorRegistry>>,
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
|
worker_id: Option<WorkerId>,
|
||||||
page_error: PageError,
|
page_error: PageError,
|
||||||
browsing_contexts: &HashMap<BrowsingContextId, String>,
|
browsing_contexts: &HashMap<BrowsingContextId, String>,
|
||||||
pipelines: &HashMap<PipelineId, BrowsingContextId>,
|
actor_workers: &HashMap<WorkerId, String>,
|
||||||
) {
|
|
||||||
let console_actor_name = match find_console_actor(
|
|
||||||
actors.clone(),
|
|
||||||
id,
|
|
||||||
None,
|
|
||||||
&HashMap::new(),
|
|
||||||
browsing_contexts,
|
|
||||||
pipelines,
|
|
||||||
) {
|
|
||||||
Some(name) => name,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
let actors = actors.lock().unwrap();
|
|
||||||
let console_actor = actors.find::<ConsoleActor>(&console_actor_name);
|
|
||||||
let browsing_context_actor =
|
|
||||||
actors.find::<BrowsingContextActor>(&console_actor.browsing_context);
|
|
||||||
console_actor.handle_page_error(page_error, id, &browsing_context_actor);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_console_message(
|
|
||||||
actors: Arc<Mutex<ActorRegistry>>,
|
|
||||||
id: PipelineId,
|
|
||||||
worker_id: Option<WorkerId>,
|
|
||||||
console_message: ConsoleMessage,
|
|
||||||
browsing_contexts: &HashMap<BrowsingContextId, String>,
|
|
||||||
actor_workers: &HashMap<(PipelineId, WorkerId), String>,
|
|
||||||
pipelines: &HashMap<PipelineId, BrowsingContextId>,
|
pipelines: &HashMap<PipelineId, BrowsingContextId>,
|
||||||
) {
|
) {
|
||||||
let console_actor_name = match find_console_actor(
|
let console_actor_name = match find_console_actor(
|
||||||
|
@ -363,22 +358,47 @@ fn run_server(
|
||||||
};
|
};
|
||||||
let actors = actors.lock().unwrap();
|
let actors = actors.lock().unwrap();
|
||||||
let console_actor = actors.find::<ConsoleActor>(&console_actor_name);
|
let console_actor = actors.find::<ConsoleActor>(&console_actor_name);
|
||||||
let browsing_context_actor =
|
let id = worker_id.map_or(UniqueId::Pipeline(id), UniqueId::Worker);
|
||||||
actors.find::<BrowsingContextActor>(&console_actor.browsing_context);
|
console_actor.handle_page_error(page_error, id, &*actors);
|
||||||
console_actor.handle_console_api(console_message, id, &browsing_context_actor);
|
}
|
||||||
|
|
||||||
|
fn handle_console_message(
|
||||||
|
actors: Arc<Mutex<ActorRegistry>>,
|
||||||
|
id: PipelineId,
|
||||||
|
worker_id: Option<WorkerId>,
|
||||||
|
console_message: ConsoleMessage,
|
||||||
|
browsing_contexts: &HashMap<BrowsingContextId, String>,
|
||||||
|
actor_workers: &HashMap<WorkerId, String>,
|
||||||
|
pipelines: &HashMap<PipelineId, BrowsingContextId>,
|
||||||
|
) {
|
||||||
|
let console_actor_name = match find_console_actor(
|
||||||
|
actors.clone(),
|
||||||
|
id,
|
||||||
|
worker_id,
|
||||||
|
actor_workers,
|
||||||
|
browsing_contexts,
|
||||||
|
pipelines,
|
||||||
|
) {
|
||||||
|
Some(name) => name,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
let actors = actors.lock().unwrap();
|
||||||
|
let console_actor = actors.find::<ConsoleActor>(&console_actor_name);
|
||||||
|
let id = worker_id.map_or(UniqueId::Pipeline(id), UniqueId::Worker);
|
||||||
|
console_actor.handle_console_api(console_message, id, &*actors);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_console_actor(
|
fn find_console_actor(
|
||||||
actors: Arc<Mutex<ActorRegistry>>,
|
actors: Arc<Mutex<ActorRegistry>>,
|
||||||
pipeline: PipelineId,
|
pipeline: PipelineId,
|
||||||
worker_id: Option<WorkerId>,
|
worker_id: Option<WorkerId>,
|
||||||
actor_workers: &HashMap<(PipelineId, WorkerId), String>,
|
actor_workers: &HashMap<WorkerId, String>,
|
||||||
browsing_contexts: &HashMap<BrowsingContextId, String>,
|
browsing_contexts: &HashMap<BrowsingContextId, String>,
|
||||||
pipelines: &HashMap<PipelineId, BrowsingContextId>,
|
pipelines: &HashMap<PipelineId, BrowsingContextId>,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
let actors = actors.lock().unwrap();
|
let actors = actors.lock().unwrap();
|
||||||
if let Some(worker_id) = worker_id {
|
if let Some(worker_id) = worker_id {
|
||||||
let actor_name = (*actor_workers).get(&(pipeline, worker_id))?;
|
let actor_name = actor_workers.get(&worker_id)?;
|
||||||
Some(actors.find::<WorkerActor>(actor_name).console.clone())
|
Some(actors.find::<WorkerActor>(actor_name).console.clone())
|
||||||
} else {
|
} else {
|
||||||
let id = pipelines.get(&pipeline)?;
|
let id = pipelines.get(&pipeline)?;
|
||||||
|
@ -397,7 +417,7 @@ fn run_server(
|
||||||
mut connections: Vec<TcpStream>,
|
mut connections: Vec<TcpStream>,
|
||||||
browsing_contexts: &HashMap<BrowsingContextId, String>,
|
browsing_contexts: &HashMap<BrowsingContextId, String>,
|
||||||
actor_requests: &mut HashMap<String, String>,
|
actor_requests: &mut HashMap<String, String>,
|
||||||
actor_workers: &HashMap<(PipelineId, WorkerId), String>,
|
actor_workers: &HashMap<WorkerId, String>,
|
||||||
pipelines: &HashMap<PipelineId, BrowsingContextId>,
|
pipelines: &HashMap<PipelineId, BrowsingContextId>,
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
request_id: String,
|
request_id: String,
|
||||||
|
@ -570,6 +590,7 @@ fn run_server(
|
||||||
.expect("Thread spawning failed");
|
.expect("Thread spawning failed");
|
||||||
|
|
||||||
while let Ok(msg) = receiver.recv() {
|
while let Ok(msg) = receiver.recv() {
|
||||||
|
debug!("{:?}", msg);
|
||||||
match msg {
|
match msg {
|
||||||
DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::AddClient(stream)) => {
|
DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::AddClient(stream)) => {
|
||||||
let actors = actors.clone();
|
let actors = actors.clone();
|
||||||
|
@ -619,8 +640,10 @@ fn run_server(
|
||||||
)) => handle_page_error(
|
)) => handle_page_error(
|
||||||
actors.clone(),
|
actors.clone(),
|
||||||
id,
|
id,
|
||||||
|
None,
|
||||||
page_error,
|
page_error,
|
||||||
&browsing_contexts,
|
&browsing_contexts,
|
||||||
|
&actor_workers,
|
||||||
&pipelines,
|
&pipelines,
|
||||||
),
|
),
|
||||||
DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::ReportCSSError(
|
DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::ReportCSSError(
|
||||||
|
|
|
@ -80,7 +80,7 @@ pub enum ScriptToDevtoolsControlMsg {
|
||||||
/// A new global object was created, associated with a particular pipeline.
|
/// A new global object was created, associated with a particular pipeline.
|
||||||
/// The means of communicating directly with it are provided.
|
/// The means of communicating directly with it are provided.
|
||||||
NewGlobal(
|
NewGlobal(
|
||||||
(Option<BrowsingContextId>, PipelineId, Option<WorkerId>),
|
(BrowsingContextId, PipelineId, Option<WorkerId>),
|
||||||
IpcSender<DevtoolScriptControlMsg>,
|
IpcSender<DevtoolScriptControlMsg>,
|
||||||
DevtoolsPageInfo,
|
DevtoolsPageInfo,
|
||||||
),
|
),
|
||||||
|
|
|
@ -43,7 +43,7 @@ use js::jsapi::JS_AddInterruptCallback;
|
||||||
use js::jsapi::{Heap, JSContext, JSObject};
|
use js::jsapi::{Heap, JSContext, JSObject};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
|
use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
|
||||||
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId};
|
use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId};
|
||||||
use net_traits::image_cache::ImageCache;
|
use net_traits::image_cache::ImageCache;
|
||||||
use net_traits::request::{CredentialsMode, Destination, ParserMetadata};
|
use net_traits::request::{CredentialsMode, Destination, ParserMetadata};
|
||||||
use net_traits::request::{Referrer, RequestBuilder, RequestMode};
|
use net_traits::request::{Referrer, RequestBuilder, RequestMode};
|
||||||
|
@ -180,6 +180,7 @@ pub struct DedicatedWorkerGlobalScope {
|
||||||
parent_sender: Box<dyn ScriptChan + Send>,
|
parent_sender: Box<dyn ScriptChan + Send>,
|
||||||
#[ignore_malloc_size_of = "Arc"]
|
#[ignore_malloc_size_of = "Arc"]
|
||||||
image_cache: Arc<dyn ImageCache>,
|
image_cache: Arc<dyn ImageCache>,
|
||||||
|
browsing_context: Option<BrowsingContextId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkerEventLoopMethods for DedicatedWorkerGlobalScope {
|
impl WorkerEventLoopMethods for DedicatedWorkerGlobalScope {
|
||||||
|
@ -221,6 +222,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
receiver: Receiver<DedicatedWorkerScriptMsg>,
|
receiver: Receiver<DedicatedWorkerScriptMsg>,
|
||||||
closing: Arc<AtomicBool>,
|
closing: Arc<AtomicBool>,
|
||||||
image_cache: Arc<dyn ImageCache>,
|
image_cache: Arc<dyn ImageCache>,
|
||||||
|
browsing_context: Option<BrowsingContextId>,
|
||||||
) -> DedicatedWorkerGlobalScope {
|
) -> DedicatedWorkerGlobalScope {
|
||||||
DedicatedWorkerGlobalScope {
|
DedicatedWorkerGlobalScope {
|
||||||
workerglobalscope: WorkerGlobalScope::new_inherited(
|
workerglobalscope: WorkerGlobalScope::new_inherited(
|
||||||
|
@ -237,6 +239,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
parent_sender: parent_sender,
|
parent_sender: parent_sender,
|
||||||
worker: DomRefCell::new(None),
|
worker: DomRefCell::new(None),
|
||||||
image_cache: image_cache,
|
image_cache: image_cache,
|
||||||
|
browsing_context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,6 +256,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
receiver: Receiver<DedicatedWorkerScriptMsg>,
|
receiver: Receiver<DedicatedWorkerScriptMsg>,
|
||||||
closing: Arc<AtomicBool>,
|
closing: Arc<AtomicBool>,
|
||||||
image_cache: Arc<dyn ImageCache>,
|
image_cache: Arc<dyn ImageCache>,
|
||||||
|
browsing_context: Option<BrowsingContextId>,
|
||||||
) -> DomRoot<DedicatedWorkerGlobalScope> {
|
) -> DomRoot<DedicatedWorkerGlobalScope> {
|
||||||
let cx = runtime.cx();
|
let cx = runtime.cx();
|
||||||
let scope = Box::new(DedicatedWorkerGlobalScope::new_inherited(
|
let scope = Box::new(DedicatedWorkerGlobalScope::new_inherited(
|
||||||
|
@ -267,6 +271,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
receiver,
|
receiver,
|
||||||
closing,
|
closing,
|
||||||
image_cache,
|
image_cache,
|
||||||
|
browsing_context,
|
||||||
));
|
));
|
||||||
unsafe { DedicatedWorkerGlobalScopeBinding::Wrap(SafeJSContext::from_ptr(cx), scope) }
|
unsafe { DedicatedWorkerGlobalScopeBinding::Wrap(SafeJSContext::from_ptr(cx), scope) }
|
||||||
}
|
}
|
||||||
|
@ -286,6 +291,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
worker_type: WorkerType,
|
worker_type: WorkerType,
|
||||||
closing: Arc<AtomicBool>,
|
closing: Arc<AtomicBool>,
|
||||||
image_cache: Arc<dyn ImageCache>,
|
image_cache: Arc<dyn ImageCache>,
|
||||||
|
browsing_context: Option<BrowsingContextId>,
|
||||||
) {
|
) {
|
||||||
let serialized_worker_url = worker_url.to_string();
|
let serialized_worker_url = worker_url.to_string();
|
||||||
let name = format!("WebWorker for {}", serialized_worker_url);
|
let name = format!("WebWorker for {}", serialized_worker_url);
|
||||||
|
@ -354,6 +360,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
receiver,
|
receiver,
|
||||||
closing,
|
closing,
|
||||||
image_cache,
|
image_cache,
|
||||||
|
browsing_context,
|
||||||
);
|
);
|
||||||
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
|
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
|
||||||
// registration (#6631), so we instead use a random number and cross our fingers.
|
// registration (#6631), so we instead use a random number and cross our fingers.
|
||||||
|
@ -467,6 +474,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_mixed_message(&self, msg: MixedMessage) {
|
fn handle_mixed_message(&self, msg: MixedMessage) {
|
||||||
|
// FIXME(#26324): `self.worker` is None in devtools messages.
|
||||||
match msg {
|
match msg {
|
||||||
MixedMessage::FromDevtools(msg) => match msg {
|
MixedMessage::FromDevtools(msg) => match msg {
|
||||||
DevtoolScriptControlMsg::EvaluateJS(_pipe_id, string, sender) => {
|
DevtoolScriptControlMsg::EvaluateJS(_pipe_id, string, sender) => {
|
||||||
|
@ -551,6 +559,10 @@ impl DedicatedWorkerGlobalScope {
|
||||||
.expect("Sending to parent failed");
|
.expect("Sending to parent failed");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn browsing_context(&self) -> Option<BrowsingContextId> {
|
||||||
|
self.browsing_context
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl ServiceWorkerRegistration {
|
||||||
|
|
||||||
let worker_id = WorkerId(Uuid::new_v4());
|
let worker_id = WorkerId(Uuid::new_v4());
|
||||||
let devtools_chan = global.devtools_chan().cloned();
|
let devtools_chan = global.devtools_chan().cloned();
|
||||||
let init = prepare_workerscope_init(&global, None);
|
let init = prepare_workerscope_init(&global, None, None);
|
||||||
ScopeThings {
|
ScopeThings {
|
||||||
script_url: script_url,
|
script_url: script_url,
|
||||||
init: init,
|
init: init,
|
||||||
|
|
|
@ -20,6 +20,7 @@ use crate::dom::dedicatedworkerglobalscope::{
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::messageevent::MessageEvent;
|
use crate::dom::messageevent::MessageEvent;
|
||||||
|
use crate::dom::window::Window;
|
||||||
use crate::dom::workerglobalscope::prepare_workerscope_init;
|
use crate::dom::workerglobalscope::prepare_workerscope_init;
|
||||||
use crate::realms::enter_realm;
|
use crate::realms::enter_realm;
|
||||||
use crate::script_runtime::JSContext;
|
use crate::script_runtime::JSContext;
|
||||||
|
@ -95,23 +96,34 @@ impl Worker {
|
||||||
pipeline_id: global.pipeline_id(),
|
pipeline_id: global.pipeline_id(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let browsing_context = global
|
||||||
|
.downcast::<Window>()
|
||||||
|
.map(|w| w.window_proxy().browsing_context_id())
|
||||||
|
.or_else(|| {
|
||||||
|
global
|
||||||
|
.downcast::<DedicatedWorkerGlobalScope>()
|
||||||
|
.and_then(|w| w.browsing_context())
|
||||||
|
});
|
||||||
|
|
||||||
let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
||||||
let worker_id = WorkerId(Uuid::new_v4());
|
let worker_id = WorkerId(Uuid::new_v4());
|
||||||
if let Some(ref chan) = global.devtools_chan() {
|
if let Some(ref chan) = global.devtools_chan() {
|
||||||
let pipeline_id = global.pipeline_id();
|
let pipeline_id = global.pipeline_id();
|
||||||
let title = format!("Worker for {}", worker_url);
|
let title = format!("Worker for {}", worker_url);
|
||||||
let page_info = DevtoolsPageInfo {
|
if let Some(browsing_context) = browsing_context {
|
||||||
title: title,
|
let page_info = DevtoolsPageInfo {
|
||||||
url: worker_url.clone(),
|
title: title,
|
||||||
};
|
url: worker_url.clone(),
|
||||||
let _ = chan.send(ScriptToDevtoolsControlMsg::NewGlobal(
|
};
|
||||||
(None, pipeline_id, Some(worker_id)),
|
let _ = chan.send(ScriptToDevtoolsControlMsg::NewGlobal(
|
||||||
devtools_sender.clone(),
|
(browsing_context, pipeline_id, Some(worker_id)),
|
||||||
page_info,
|
devtools_sender.clone(),
|
||||||
));
|
page_info,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let init = prepare_workerscope_init(global, Some(devtools_sender));
|
let init = prepare_workerscope_init(global, Some(devtools_sender), Some(worker_id));
|
||||||
|
|
||||||
DedicatedWorkerGlobalScope::run_worker_scope(
|
DedicatedWorkerGlobalScope::run_worker_scope(
|
||||||
init,
|
init,
|
||||||
|
@ -126,6 +138,7 @@ impl Worker {
|
||||||
worker_options.type_,
|
worker_options.type_,
|
||||||
closing,
|
closing,
|
||||||
global.image_cache(),
|
global.image_cache(),
|
||||||
|
browsing_context,
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(worker)
|
Ok(worker)
|
||||||
|
|
|
@ -62,6 +62,7 @@ use uuid::Uuid;
|
||||||
pub fn prepare_workerscope_init(
|
pub fn prepare_workerscope_init(
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
|
devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
|
||||||
|
worker_id: Option<WorkerId>,
|
||||||
) -> WorkerGlobalScopeInit {
|
) -> WorkerGlobalScopeInit {
|
||||||
let init = WorkerGlobalScopeInit {
|
let init = WorkerGlobalScopeInit {
|
||||||
resource_threads: global.resource_threads().clone(),
|
resource_threads: global.resource_threads().clone(),
|
||||||
|
@ -71,7 +72,7 @@ pub fn prepare_workerscope_init(
|
||||||
from_devtools_sender: devtools_sender,
|
from_devtools_sender: devtools_sender,
|
||||||
script_to_constellation_chan: global.script_to_constellation_chan().clone(),
|
script_to_constellation_chan: global.script_to_constellation_chan().clone(),
|
||||||
scheduler_chan: global.scheduler_chan().clone(),
|
scheduler_chan: global.scheduler_chan().clone(),
|
||||||
worker_id: WorkerId(Uuid::new_v4()),
|
worker_id: worker_id.unwrap_or_else(|| WorkerId(Uuid::new_v4())),
|
||||||
pipeline_id: global.pipeline_id(),
|
pipeline_id: global.pipeline_id(),
|
||||||
origin: global.origin().immutable().clone(),
|
origin: global.origin().immutable().clone(),
|
||||||
is_headless: global.is_headless(),
|
is_headless: global.is_headless(),
|
||||||
|
|
|
@ -3384,7 +3384,7 @@ impl ScriptThread {
|
||||||
url: url,
|
url: url,
|
||||||
};
|
};
|
||||||
chan.send(ScriptToDevtoolsControlMsg::NewGlobal(
|
chan.send(ScriptToDevtoolsControlMsg::NewGlobal(
|
||||||
(Some(bc), p, w),
|
(bc, p, w),
|
||||||
self.devtools_sender.clone(),
|
self.devtools_sender.clone(),
|
||||||
page_info.clone(),
|
page_info.clone(),
|
||||||
))
|
))
|
||||||
|
|
|
@ -11,7 +11,6 @@ use crate::dom::abstractworker::WorkerScriptMsg;
|
||||||
use crate::dom::serviceworkerglobalscope::{ServiceWorkerGlobalScope, ServiceWorkerScriptMsg};
|
use crate::dom::serviceworkerglobalscope::{ServiceWorkerGlobalScope, ServiceWorkerScriptMsg};
|
||||||
use crate::dom::serviceworkerregistration::longest_prefix_match;
|
use crate::dom::serviceworkerregistration::longest_prefix_match;
|
||||||
use crossbeam_channel::{unbounded, Receiver, RecvError, Sender};
|
use crossbeam_channel::{unbounded, Receiver, RecvError, Sender};
|
||||||
use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg};
|
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use net_traits::{CoreResourceMsg, CustomResponseMediator};
|
use net_traits::{CoreResourceMsg, CustomResponseMediator};
|
||||||
|
@ -79,23 +78,7 @@ impl ServiceWorkerManager {
|
||||||
let scope_things = self.registered_workers.get(&scope_url);
|
let scope_things = self.registered_workers.get(&scope_url);
|
||||||
if let Some(scope_things) = scope_things {
|
if let Some(scope_things) = scope_things {
|
||||||
let (sender, receiver) = unbounded();
|
let (sender, receiver) = unbounded();
|
||||||
let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
let (_devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
||||||
if let Some(ref chan) = scope_things.devtools_chan {
|
|
||||||
let title = format!("ServiceWorker for {}", scope_things.script_url);
|
|
||||||
let page_info = DevtoolsPageInfo {
|
|
||||||
title: title,
|
|
||||||
url: scope_things.script_url.clone(),
|
|
||||||
};
|
|
||||||
let _ = chan.send(ScriptToDevtoolsControlMsg::NewGlobal(
|
|
||||||
(
|
|
||||||
None,
|
|
||||||
scope_things.init.pipeline_id,
|
|
||||||
Some(scope_things.worker_id),
|
|
||||||
),
|
|
||||||
devtools_sender,
|
|
||||||
page_info,
|
|
||||||
));
|
|
||||||
};
|
|
||||||
ServiceWorkerGlobalScope::run_serviceworker_scope(
|
ServiceWorkerGlobalScope::run_serviceworker_scope(
|
||||||
scope_things.clone(),
|
scope_things.clone(),
|
||||||
sender.clone(),
|
sender.clone(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue