aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2019-12-13 20:59:49 -0500
committerGitHub <noreply@github.com>2019-12-13 20:59:49 -0500
commitecaf65408cd9a555cb36ace00b005fc6eec453c9 (patch)
treedea0398c51009f73a0bc8f4e61baa4371d6a9a9f
parentf1044d11cad71ce7523eca258f31a3c97e99b857 (diff)
parent84074d3c8687b3297844ae4be64fc210f576bd21 (diff)
downloadservo-ecaf65408cd9a555cb36ace00b005fc6eec453c9.tar.gz
servo-ecaf65408cd9a555cb36ace00b005fc6eec453c9.zip
Auto merge of #25288 - jdm:devtools-revival, r=manishearth
Update devtools server for Firefox 71. Based on reading code under https://searchfox.org/mozilla-central/source/devtools/shared/specs/, https://searchfox.org/mozilla-central/source/devtools/shared/front/, https://searchfox.org/mozilla-central/source/devtools/shared/specs/, and https://searchfox.org/mozilla-central/source/devtools/server/actors/, as well as dumping the protocol output when using Firefox to debug itself. This makes the JS console usable again in nightly Firefox from about:debugging. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #24092 - [x] These changes do not require tests because ha ha ha devtools tests.
-rw-r--r--components/devtools/actors/browsing_context.rs53
-rw-r--r--components/devtools/actors/console.rs14
-rw-r--r--components/devtools/actors/device.rs2
-rw-r--r--components/devtools/actors/preference.rs81
-rw-r--r--components/devtools/actors/process.rs51
-rw-r--r--components/devtools/actors/root.rs100
-rw-r--r--components/devtools/actors/stylesheets.rs28
-rw-r--r--components/devtools/actors/thread.rs19
-rw-r--r--components/devtools/lib.rs12
9 files changed, 339 insertions, 21 deletions
diff --git a/components/devtools/actors/browsing_context.rs b/components/devtools/actors/browsing_context.rs
index dcc9fb84a6e..bdc468f9f84 100644
--- a/components/devtools/actors/browsing_context.rs
+++ b/components/devtools/actors/browsing_context.rs
@@ -15,7 +15,18 @@ use serde_json::{Map, Value};
use std::net::TcpStream;
#[derive(Serialize)]
-struct BrowsingContextTraits;
+struct BrowsingContextTraits {
+ isBrowsingContext: bool,
+}
+
+#[derive(Serialize)]
+struct AttachedTraits {
+ reconfigure: bool,
+ frames: bool,
+ logInPage: bool,
+ canRewind: bool,
+ watchpoints: bool,
+}
#[derive(Serialize)]
struct BrowsingContextAttachedReply {
@@ -25,7 +36,7 @@ struct BrowsingContextAttachedReply {
threadActor: String,
cacheDisabled: bool,
javascriptEnabled: bool,
- traits: BrowsingContextTraits,
+ traits: AttachedTraits,
}
#[derive(Serialize)]
@@ -71,6 +82,7 @@ pub struct BrowsingContextActorMsg {
title: String,
url: String,
outerWindowID: u32,
+ browsingContextId: u32,
consoleActor: String,
emulationActor: String,
inspectorActor: String,
@@ -78,6 +90,20 @@ pub struct BrowsingContextActorMsg {
profilerActor: String,
performanceActor: String,
styleSheetsActor: String,
+ traits: BrowsingContextTraits,
+ // Part of the official protocol, but not yet implemented.
+ /*storageActor: String,
+ memoryActor: String,
+ framerateActor: String,
+ reflowActor: String,
+ cssPropertiesActor: String,
+ animationsActor: String,
+ webExtensionInspectedWindowActor: String,
+ accessibilityActor: String,
+ screenshotActor: String,
+ changesActor: String,
+ webSocketActor: String,
+ manifestActor: String,*/
}
pub struct BrowsingContextActor {
@@ -127,11 +153,17 @@ impl Actor for BrowsingContextActor {
"attach" => {
let msg = BrowsingContextAttachedReply {
from: self.name(),
- type_: "targetAttached".to_owned(),
+ type_: "tabAttached".to_owned(),
threadActor: self.thread.clone(),
cacheDisabled: false,
javascriptEnabled: true,
- traits: BrowsingContextTraits,
+ traits: AttachedTraits {
+ reconfigure: false,
+ frames: false,
+ logInPage: false,
+ canRewind: false,
+ watchpoints: false,
+ },
};
let console_actor = registry.find::<ConsoleActor>(&self.console);
console_actor
@@ -166,7 +198,12 @@ impl Actor for BrowsingContextActor {
"listFrames" => {
let msg = ListFramesReply {
from: self.name(),
- frames: vec![],
+ frames: vec![FrameMsg {
+ id: 0, //FIXME should match outerwindow id
+ parentID: 0,
+ url: self.url.clone(),
+ title: self.title.clone(),
+ }],
};
stream.write_json_packet(&msg);
ActorMessageStatus::Processed
@@ -190,9 +227,13 @@ impl BrowsingContextActor {
pub fn encodable(&self) -> BrowsingContextActorMsg {
BrowsingContextActorMsg {
actor: self.name(),
+ traits: BrowsingContextTraits {
+ isBrowsingContext: true,
+ },
title: self.title.clone(),
url: self.url.clone(),
- outerWindowID: 0, //FIXME: this should probably be the pipeline id
+ browsingContextId: 0, //FIXME should come from constellation
+ outerWindowID: 0, //FIXME: this should probably be the pipeline id
consoleActor: self.console.clone(),
emulationActor: self.emulation.clone(),
inspectorActor: self.inspector.clone(),
diff --git a/components/devtools/actors/console.rs b/components/devtools/actors/console.rs
index c50d1a7b40c..845e39075b1 100644
--- a/components/devtools/actors/console.rs
+++ b/components/devtools/actors/console.rs
@@ -39,9 +39,7 @@ impl EncodableConsoleMessage for CachedConsoleMessage {
}
#[derive(Serialize)]
-struct StartedListenersTraits {
- customNetworkRequest: bool,
-}
+struct StartedListenersTraits;
#[derive(Serialize)]
struct StartedListenersReply {
@@ -309,13 +307,15 @@ impl Actor for ConsoleActor {
"startListeners" => {
//TODO: actually implement listener filters that support starting/stopping
+ let listeners = msg.get("listeners").unwrap().as_array().unwrap().to_owned();
let msg = StartedListenersReply {
from: self.name(),
nativeConsoleAPI: true,
- startedListeners: vec!["PageError".to_owned(), "ConsoleAPI".to_owned()],
- traits: StartedListenersTraits {
- customNetworkRequest: true,
- },
+ startedListeners: listeners
+ .into_iter()
+ .map(|s| s.as_str().unwrap().to_owned())
+ .collect(),
+ traits: StartedListenersTraits,
};
stream.write_json_packet(&msg);
ActorMessageStatus::Processed
diff --git a/components/devtools/actors/device.rs b/components/devtools/actors/device.rs
index bd757f00eab..11785d8c0b8 100644
--- a/components/devtools/actors/device.rs
+++ b/components/devtools/actors/device.rs
@@ -41,7 +41,7 @@ impl Actor for DeviceActor {
from: self.name(),
value: SystemInfo {
apptype: "servo".to_string(),
- platformVersion: "63.0".to_string(),
+ platformVersion: "71.0".to_string(),
},
};
stream.write_json_packet(&msg);
diff --git a/components/devtools/actors/preference.rs b/components/devtools/actors/preference.rs
new file mode 100644
index 00000000000..aefd8638631
--- /dev/null
+++ b/components/devtools/actors/preference.rs
@@ -0,0 +1,81 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
+use crate::protocol::JsonPacketStream;
+use serde_json::{Map, Value};
+use std::net::TcpStream;
+
+pub struct PreferenceActor {
+ name: String,
+}
+
+impl PreferenceActor {
+ pub fn new(name: String) -> Self {
+ Self { name }
+ }
+}
+
+impl Actor for PreferenceActor {
+ fn name(&self) -> String {
+ self.name.clone()
+ }
+
+ fn handle_message(
+ &self,
+ _registry: &ActorRegistry,
+ msg_type: &str,
+ _msg: &Map<String, Value>,
+ stream: &mut TcpStream,
+ ) -> Result<ActorMessageStatus, ()> {
+ Ok(match msg_type {
+ "getBoolPref" => {
+ let reply = BoolReply {
+ from: self.name(),
+ value: false,
+ };
+ stream.write_json_packet(&reply);
+ ActorMessageStatus::Processed
+ },
+
+ "getCharPref" => {
+ let reply = CharReply {
+ from: self.name(),
+ value: "".to_owned(),
+ };
+ stream.write_json_packet(&reply);
+ ActorMessageStatus::Processed
+ },
+
+ "getIntPref" => {
+ let reply = IntReply {
+ from: self.name(),
+ value: 0,
+ };
+ stream.write_json_packet(&reply);
+ ActorMessageStatus::Processed
+ },
+
+ _ => ActorMessageStatus::Ignored,
+ })
+ }
+}
+
+#[derive(Serialize)]
+struct BoolReply {
+ from: String,
+ value: bool,
+}
+
+#[derive(Serialize)]
+struct CharReply {
+ from: String,
+ value: String,
+}
+
+#[derive(Serialize)]
+struct IntReply {
+ from: String,
+ value: i32,
+}
diff --git a/components/devtools/actors/process.rs b/components/devtools/actors/process.rs
new file mode 100644
index 00000000000..de9a9f96ed1
--- /dev/null
+++ b/components/devtools/actors/process.rs
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
+use crate::protocol::JsonPacketStream;
+use serde_json::{Map, Value};
+use std::net::TcpStream;
+
+#[derive(Serialize)]
+struct ListWorkersReply {
+ from: String,
+ workers: Vec<u32>, // TODO: use proper JSON structure.
+}
+
+pub struct ProcessActor {
+ name: String,
+}
+
+impl ProcessActor {
+ pub fn new(name: String) -> Self {
+ Self { name }
+ }
+}
+
+impl Actor for ProcessActor {
+ fn name(&self) -> String {
+ self.name.clone()
+ }
+
+ fn handle_message(
+ &self,
+ _registry: &ActorRegistry,
+ msg_type: &str,
+ _msg: &Map<String, Value>,
+ stream: &mut TcpStream,
+ ) -> Result<ActorMessageStatus, ()> {
+ Ok(match msg_type {
+ "listWorkers" => {
+ let reply = ListWorkersReply {
+ from: self.name(),
+ workers: vec![],
+ };
+ stream.write_json_packet(&reply);
+ ActorMessageStatus::Processed
+ },
+
+ _ => ActorMessageStatus::Ignored,
+ })
+ }
+}
diff --git a/components/devtools/actors/root.rs b/components/devtools/actors/root.rs
index ef19a5d279a..da7483ffb34 100644
--- a/components/devtools/actors/root.rs
+++ b/components/devtools/actors/root.rs
@@ -37,6 +37,7 @@ struct GetRootReply {
selected: u32,
performanceActor: String,
deviceActor: String,
+ preferenceActor: String,
}
#[derive(Serialize)]
@@ -47,6 +48,12 @@ struct ListTabsReply {
}
#[derive(Serialize)]
+struct GetTabReply {
+ from: String,
+ tab: BrowsingContextActorMsg,
+}
+
+#[derive(Serialize)]
pub struct RootActorMsg {
from: String,
applicationType: String,
@@ -60,15 +67,53 @@ pub struct ProtocolDescriptionReply {
}
#[derive(Serialize)]
+struct ListWorkersReply {
+ from: String,
+ workers: Vec<WorkerMsg>,
+}
+
+#[derive(Serialize)]
+struct WorkerMsg {
+ id: u32,
+}
+
+#[derive(Serialize)]
+struct ListServiceWorkerRegistrationsReply {
+ from: String,
+ registrations: Vec<u32>, // TODO: follow actual JSON structure.
+}
+
+#[derive(Serialize)]
pub struct Types {
performance: ActorDescription,
device: ActorDescription,
}
+#[derive(Serialize)]
+struct ListProcessesResponse {
+ from: String,
+ processes: Vec<ProcessForm>,
+}
+
+#[derive(Serialize)]
+struct ProcessForm {
+ actor: String,
+ id: u32,
+ isParent: bool,
+}
+
+#[derive(Serialize)]
+struct GetProcessResponse {
+ from: String,
+ form: ProcessForm,
+}
+
pub struct RootActor {
pub tabs: Vec<String>,
pub performance: String,
pub device: String,
+ pub preference: String,
+ pub process: String,
}
impl Actor for RootActor {
@@ -93,12 +138,39 @@ impl Actor for RootActor {
ActorMessageStatus::Processed
},
+ "listProcesses" => {
+ let reply = ListProcessesResponse {
+ from: self.name(),
+ processes: vec![ProcessForm {
+ actor: self.process.clone(),
+ id: 0,
+ isParent: true,
+ }],
+ };
+ stream.write_json_packet(&reply);
+ ActorMessageStatus::Processed
+ },
+
+ "getProcess" => {
+ let reply = GetProcessResponse {
+ from: self.name(),
+ form: ProcessForm {
+ actor: self.process.clone(),
+ id: 0,
+ isParent: true,
+ },
+ };
+ stream.write_json_packet(&reply);
+ ActorMessageStatus::Processed
+ },
+
"getRoot" => {
let actor = GetRootReply {
from: "root".to_owned(),
selected: 0,
performanceActor: self.performance.clone(),
deviceActor: self.device.clone(),
+ preferenceActor: self.preference.clone(),
};
stream.write_json_packet(&actor);
ActorMessageStatus::Processed
@@ -119,6 +191,34 @@ impl Actor for RootActor {
ActorMessageStatus::Processed
},
+ "listServiceWorkerRegistrations" => {
+ let reply = ListServiceWorkerRegistrationsReply {
+ from: self.name(),
+ registrations: vec![],
+ };
+ stream.write_json_packet(&reply);
+ ActorMessageStatus::Processed
+ },
+
+ "listWorkers" => {
+ let reply = ListWorkersReply {
+ from: self.name(),
+ workers: vec![],
+ };
+ stream.write_json_packet(&reply);
+ ActorMessageStatus::Processed
+ },
+
+ "getTab" => {
+ let tab = registry.find::<BrowsingContextActor>(&self.tabs[0]);
+ let reply = GetTabReply {
+ from: self.name(),
+ tab: tab.encodable(),
+ };
+ stream.write_json_packet(&reply);
+ ActorMessageStatus::Processed
+ },
+
"protocolDescription" => {
let msg = ProtocolDescriptionReply {
from: self.name(),
diff --git a/components/devtools/actors/stylesheets.rs b/components/devtools/actors/stylesheets.rs
index 00d1ec74dd1..ccec3a7d30f 100644
--- a/components/devtools/actors/stylesheets.rs
+++ b/components/devtools/actors/stylesheets.rs
@@ -3,9 +3,16 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
+use crate::protocol::JsonPacketStream;
use serde_json::{Map, Value};
use std::net::TcpStream;
+#[derive(Serialize)]
+struct GetStyleSheetsReply {
+ from: String,
+ styleSheets: Vec<u32>, // TODO: real JSON structure.
+}
+
pub struct StyleSheetsActor {
pub name: String,
}
@@ -16,12 +23,23 @@ impl Actor for StyleSheetsActor {
}
fn handle_message(
&self,
- _: &ActorRegistry,
- _: &str,
- _: &Map<String, Value>,
- _: &mut TcpStream,
+ _registry: &ActorRegistry,
+ msg_type: &str,
+ _msg: &Map<String, Value>,
+ stream: &mut TcpStream,
) -> Result<ActorMessageStatus, ()> {
- Ok(ActorMessageStatus::Ignored)
+ Ok(match msg_type {
+ "getStyleSheets" => {
+ let msg = GetStyleSheetsReply {
+ from: self.name(),
+ styleSheets: vec![],
+ };
+ stream.write_json_packet(&msg);
+ ActorMessageStatus::Processed
+ },
+
+ _ => ActorMessageStatus::Ignored,
+ })
}
}
diff --git a/components/devtools/actors/thread.rs b/components/devtools/actors/thread.rs
index 6ecb9e200a7..f0e2f1e98a2 100644
--- a/components/devtools/actors/thread.rs
+++ b/components/devtools/actors/thread.rs
@@ -8,11 +8,15 @@ use serde_json::{Map, Value};
use std::net::TcpStream;
#[derive(Serialize)]
-struct ThreadAttachedReply {
+struct ThreadAttached {
from: String,
#[serde(rename = "type")]
type_: String,
actor: String,
+ frame: u32,
+ error: u32,
+ recordingEndpoint: u32,
+ executionPoint: u32,
poppedFrames: Vec<PoppedFrameMsg>,
why: WhyMsg,
}
@@ -54,6 +58,11 @@ struct SourcesReply {
#[derive(Serialize)]
enum Source {}
+#[derive(Serialize)]
+struct VoidAttachedReply {
+ from: String,
+}
+
pub struct ThreadActor {
name: String,
}
@@ -78,16 +87,21 @@ impl Actor for ThreadActor {
) -> Result<ActorMessageStatus, ()> {
Ok(match msg_type {
"attach" => {
- let msg = ThreadAttachedReply {
+ let msg = ThreadAttached {
from: self.name(),
type_: "paused".to_owned(),
actor: registry.new_name("pause"),
+ frame: 0,
+ error: 0,
+ recordingEndpoint: 0,
+ executionPoint: 0,
poppedFrames: vec![],
why: WhyMsg {
type_: "attached".to_owned(),
},
};
stream.write_json_packet(&msg);
+ stream.write_json_packet(&VoidAttachedReply { from: self.name() });
ActorMessageStatus::Processed
},
@@ -97,6 +111,7 @@ impl Actor for ThreadActor {
type_: "resumed".to_owned(),
};
stream.write_json_packet(&msg);
+ stream.write_json_packet(&VoidAttachedReply { from: self.name() });
ActorMessageStatus::Processed
},
diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs
index 63e4c7aea15..7f958b2bb50 100644
--- a/components/devtools/lib.rs
+++ b/components/devtools/lib.rs
@@ -26,6 +26,8 @@ use crate::actors::framerate::FramerateActor;
use crate::actors::inspector::InspectorActor;
use crate::actors::network_event::{EventActor, NetworkEventActor, ResponseStartMsg};
use crate::actors::performance::PerformanceActor;
+use crate::actors::preference::PreferenceActor;
+use crate::actors::process::ProcessActor;
use crate::actors::profiler::ProfilerActor;
use crate::actors::root::RootActor;
use crate::actors::stylesheets::StyleSheetsActor;
@@ -60,6 +62,8 @@ mod actors {
pub mod network_event;
pub mod object;
pub mod performance;
+ pub mod preference;
+ pub mod process;
pub mod profiler;
pub mod root;
pub mod stylesheets;
@@ -156,15 +160,23 @@ fn run_server(
let device = DeviceActor::new(registry.new_name("device"));
+ let preference = PreferenceActor::new(registry.new_name("preference"));
+
+ let process = ProcessActor::new(registry.new_name("process"));
+
let root = Box::new(RootActor {
tabs: vec![],
device: device.name(),
performance: performance.name(),
+ preference: preference.name(),
+ process: process.name(),
});
registry.register(root);
registry.register(Box::new(performance));
registry.register(Box::new(device));
+ registry.register(Box::new(preference));
+ registry.register(Box::new(process));
registry.find::<RootActor>("root");
let actors = registry.create_shareable();