Add support for launching devtools server on random port

Assign random port to devtools server in case user does not specify a
port explicitly and report it to the embedding layer for display to user.
This commit is contained in:
Kunal Mohan 2020-03-07 20:23:14 +05:30
parent 6ab923c8e8
commit 94db0d61cb
No known key found for this signature in database
GPG key ID: 2B475A4524237BAC
10 changed files with 73 additions and 9 deletions

View file

@ -653,12 +653,7 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR
"Start remote debugger server on port",
"2794",
);
opts.optflagopt(
"",
"devtools",
"Start remote devtools server on port",
"6000",
);
opts.optflagopt("", "devtools", "Start remote devtools server on port", "0");
opts.optflagopt(
"",
"webdriver",
@ -886,7 +881,8 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR
})
});
let devtools_port = opt_match.opt_default("devtools", "6000").map(|port| {
// Set default port 0 for a random port to be selected.
let devtools_port = opt_match.opt_default("devtools", "0").map(|port| {
port.parse()
.unwrap_or_else(|err| args_fail(&format!("Error parsing option: --devtools ({})", err)))
});

View file

@ -154,7 +154,20 @@ fn run_server(
port: u16,
embedder: EmbedderProxy,
) {
let listener = TcpListener::bind(&("0.0.0.0", port)).unwrap();
let bound = TcpListener::bind(&("0.0.0.0", port)).ok().and_then(|l| {
l.local_addr()
.map(|addr| addr.port())
.ok()
.map(|port| (l, port))
});
let port = bound.as_ref().map(|(_, port)| *port).ok_or(());
embedder.send((None, EmbedderMsg::OnDevtoolsStarted(port)));
let listener = match bound {
Some((l, _)) => l,
None => return,
};
let mut registry = ActorRegistry::new();

View file

@ -198,6 +198,8 @@ pub enum EmbedderMsg {
/// Notifies the embedder about media session events
/// (i.e. when there is metadata for the active media session, playback state changes...).
MediaSessionEvent(MediaSessionEvent),
/// Report the status of Devtools Server
OnDevtoolsStarted(Result<u16, ()>),
}
impl Debug for EmbedderMsg {
@ -232,6 +234,7 @@ impl Debug for EmbedderMsg {
EmbedderMsg::BrowserCreated(..) => write!(f, "BrowserCreated"),
EmbedderMsg::ReportProfile(..) => write!(f, "ReportProfile"),
EmbedderMsg::MediaSessionEvent(..) => write!(f, "MediaSessionEvent"),
EmbedderMsg::OnDevtoolsStarted(..) => write!(f, "OnDevtoolsStarted"),
}
}
}

View file

@ -515,6 +515,12 @@ where
debug!("MediaSessionEvent received");
// TODO(ferjm): MediaSession support for Glutin based browsers.
},
EmbedderMsg::OnDevtoolsStarted(port) => {
match port {
Ok(p) => info!("Devtools Server running on port {}", p),
Err(()) => error!("Error running devtools server"),
}
},
}
}
}

View file

@ -423,6 +423,13 @@ impl HostTrait for HostCallbacks {
}
fn set_clipboard_contents(&self, _contents: String) {}
fn on_devtools_started(&self, port: Result<u16, ()>) {
match port {
Ok(p) => info!("Devtools Server running on port {}", p),
Err(()) => error!("Error running Devtools server"),
}
}
}
pub struct ServoInstance {

View file

@ -146,6 +146,8 @@ pub trait HostTrait {
fn on_media_session_playback_state_change(&self, state: MediaSessionPlaybackState);
/// Called when the media session position state is set.
fn on_media_session_set_position_state(&self, duration: f64, position: f64, playback_rate: f64);
/// Called when devtools server is started
fn on_devtools_started(&self, port: Result<u16, ()>);
}
pub struct ServoGlue {
@ -670,6 +672,9 @@ impl ServoGlue {
),
};
},
EmbedderMsg::OnDevtoolsStarted(port) => {
self.callbacks.host_callbacks.on_devtools_started(port);
},
EmbedderMsg::Status(..) |
EmbedderMsg::SelectFiles(..) |
EmbedderMsg::MoveTo(..) |

View file

@ -23,7 +23,7 @@ use simpleservo::{
use std::ffi::{CStr, CString};
#[cfg(target_os = "windows")]
use std::mem;
use std::os::raw::{c_char, c_void};
use std::os::raw::{c_char, c_uint, c_void};
use std::panic::{self, UnwindSafe};
use std::slice;
use std::str::FromStr;
@ -229,6 +229,7 @@ pub struct CHostCallbacks {
default: *const c_char,
trusted: bool,
) -> *const c_char,
pub on_devtools_started: extern "C" fn(result: CDevtoolsServerState, port: c_uint),
}
/// Servo options
@ -286,6 +287,12 @@ pub enum CMediaSessionPlaybackState {
Paused,
}
#[repr(C)]
pub enum CDevtoolsServerState {
Started,
Error,
}
impl From<MediaSessionPlaybackState> for CMediaSessionPlaybackState {
fn from(state: MediaSessionPlaybackState) -> Self {
match state {
@ -854,4 +861,17 @@ impl HostTrait for HostCallbacks {
let contents_str = c_str.to_str().expect("Can't create str");
Some(contents_str.to_owned())
}
fn on_devtools_started(&self, port: Result<u16, ()>) {
match port {
Ok(p) => {
info!("Devtools Server running on port {}", p);
(self.0.on_devtools_started)(CDevtoolsServerState::Started, p.into());
},
Err(()) => {
error!("Error running devtools server");
(self.0.on_devtools_started)(CDevtoolsServerState::Error, 0);
},
}
}
}

View file

@ -603,6 +603,13 @@ impl HostTrait for HostCallbacks {
)
.unwrap();
}
fn on_devtools_started(&self, port: Result<u16, ()>) {
match port {
Ok(p) => info!("Devtools Server running on port {}", p),
Err(()) => error!("Error running devtools server"),
}
}
}
fn initialize_android_glue(env: &JNIEnv, activity: JObject) {

View file

@ -87,6 +87,11 @@ const char *prompt_input(const char *message, const char *default,
}
}
void on_devtools_started(Servo::DevtoolsServerState result,
const unsigned int port) {
// FIXME
}
Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height,
float dpi, ServoDelegate &aDelegate)
: mWindowHeight(height), mWindowWidth(width), mDelegate(aDelegate) {
@ -147,6 +152,7 @@ Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height,
c.prompt_ok_cancel = &prompt_ok_cancel;
c.prompt_yes_no = &prompt_yes_no;
c.prompt_input = &prompt_input;
c.on_devtools_started = &on_devtools_started;
capi::register_panic_handler(&on_panic);

View file

@ -31,6 +31,7 @@ public:
typedef capi::CPromptResult PromptResult;
typedef capi::CMediaSessionActionType MediaSessionActionType;
typedef capi::CMediaSessionPlaybackState MediaSessionPlaybackState;
typedef capi::CDevtoolsServerState DevtoolsServerState;
void PerformUpdates() { capi::perform_updates(); }
void DeInit() { capi::deinit(); }