devtools/actors/
blackboxing.rs1use std::sync::Arc;
6
7use devtools_traits::{BlackboxCoverage, DevtoolScriptControlMsg};
8use malloc_size_of_derive::MallocSizeOf;
9use serde::Deserialize;
10
11use crate::actor::{Actor, ActorEncode, ActorError, ActorRegistry, new_actor_name};
12use crate::actors::browsing_context::BrowsingContextActor;
13use crate::actors::thread::ThreadActor;
14use crate::{ActorMsg, EmptyReplyMsg};
15
16#[derive(Deserialize)]
18struct BlackboxRequest {
19 range: Vec<BlackboxRange>,
20 url: String,
21}
22
23#[derive(Deserialize, Debug)]
24struct BlackboxRange {
25 start: BlackboxSourceLocation,
26 end: BlackboxSourceLocation,
27}
28
29#[derive(Deserialize, Debug)]
30struct BlackboxSourceLocation {
31 line: u32,
32 column: u32,
33}
34
35#[derive(MallocSizeOf)]
36pub(crate) struct BlackboxingActor {
37 name: String,
38 browsing_context_name: String,
39}
40
41impl Actor for BlackboxingActor {
42 fn name(&self) -> &str {
43 &self.name
44 }
45
46 fn handle_message(
47 &self,
48 request: crate::protocol::ClientRequest,
49 registry: &ActorRegistry,
50 msg_type: &str,
51 msg: &serde_json::Map<String, serde_json::Value>,
52 _: crate::StreamId,
53 ) -> Result<(), crate::actor::ActorError> {
54 if msg_type != "blackbox" && msg_type != "unblackbox" {
55 return Err(ActorError::UnrecognizedPacketType);
56 }
57
58 let blackbox_request: BlackboxRequest =
59 serde_json::from_value(msg.clone().into()).map_err(|_| ActorError::Internal)?;
60
61 let coverage = match &blackbox_request.range[..] {
62 [] => BlackboxCoverage::Full,
63 [range] => BlackboxCoverage::Partial(
64 (range.start.line, range.start.column),
65 (range.end.line, range.end.column),
66 ),
67 _ => {
68 log::warn!(
69 "Expected 0 or 1 range elements, got {:?}",
70 blackbox_request.range
71 );
72 return Err(ActorError::Internal);
73 },
74 };
75
76 let browsing_context_actor =
77 registry.find::<BrowsingContextActor>(&self.browsing_context_name);
78 let thread_actor = registry.find::<ThreadActor>(&browsing_context_actor.thread_name);
79 let source = thread_actor
80 .source_manager
81 .find_source(registry, &blackbox_request.url)
82 .ok_or(ActorError::Internal)?;
83
84 let control_msg = match msg_type {
85 "blackbox" => DevtoolScriptControlMsg::Blackbox(source.spidermonkey_id, coverage),
86 "unblackbox" => DevtoolScriptControlMsg::Unblackbox(source.spidermonkey_id, coverage),
87 _ => unreachable!(),
88 };
89 source
90 .script_sender
91 .send(control_msg)
92 .map_err(|_| ActorError::Internal)?;
93
94 request.reply_final(&EmptyReplyMsg {
95 from: self.name().into(),
96 })?;
97 Ok(())
98 }
99}
100
101impl BlackboxingActor {
102 pub fn register(registry: &ActorRegistry, browsing_context_name: String) -> Arc<Self> {
103 let name = new_actor_name::<Self>();
104 let actor = Self {
105 name,
106 browsing_context_name,
107 };
108 registry.register::<Self>(actor)
109 }
110}
111
112impl ActorEncode<ActorMsg> for BlackboxingActor {
113 fn encode(&self, _: &ActorRegistry) -> ActorMsg {
114 ActorMsg {
115 actor: self.name().into(),
116 }
117 }
118}