diff options
Diffstat (limited to 'components/webdriver_server/lib.rs')
-rw-r--r-- | components/webdriver_server/lib.rs | 111 |
1 files changed, 81 insertions, 30 deletions
diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index 09c466cad3c..0e3fa9058d6 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -10,11 +10,12 @@ mod actions; mod capabilities; use std::borrow::ToOwned; +use std::cell::{Cell, RefCell}; use std::collections::{BTreeMap, HashMap}; use std::io::Cursor; use std::net::{SocketAddr, SocketAddrV4}; use std::time::Duration; -use std::{env, fmt, mem, process, thread}; +use std::{env, fmt, process, thread}; use base::id::{BrowsingContextId, WebViewId}; use base64::Engine; @@ -23,8 +24,9 @@ use constellation_traits::{EmbedderToConstellationMessage, TraversalDirection}; use cookie::{CookieBuilder, Expiration}; use crossbeam_channel::{Receiver, Sender, after, select, unbounded}; use embedder_traits::{ - MouseButton, WebDriverCommandMsg, WebDriverCookieError, WebDriverFrameId, WebDriverJSError, - WebDriverJSResult, WebDriverJSValue, WebDriverLoadStatus, WebDriverScriptCommand, + MouseButton, WebDriverCommandMsg, WebDriverCommandResponse, WebDriverCookieError, + WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverJSValue, WebDriverLoadStatus, + WebDriverMessageId, WebDriverScriptCommand, }; use euclid::{Rect, Size2D}; use http::method::Method; @@ -43,8 +45,8 @@ use servo_url::ServoUrl; use style_traits::CSSPixel; use uuid::Uuid; use webdriver::actions::{ - ActionSequence, PointerDownAction, PointerMoveAction, PointerOrigin, PointerType, - PointerUpAction, + ActionSequence, ActionsType, PointerAction, PointerActionItem, PointerActionParameters, + PointerDownAction, PointerMoveAction, PointerOrigin, PointerType, PointerUpAction, }; use webdriver::capabilities::CapabilitiesMatching; use webdriver::command::{ @@ -64,6 +66,26 @@ use webdriver::server::{self, Session, SessionTeardownKind, WebDriverHandler}; use crate::actions::{InputSourceState, PointerInputState}; +#[derive(Default)] +pub struct WebDriverMessageIdGenerator { + counter: Cell<usize>, +} + +impl WebDriverMessageIdGenerator { + pub fn new() -> Self { + Self { + counter: Cell::new(0), + } + } + + /// Returns a unique ID. + pub fn next(&self) -> WebDriverMessageId { + let id = self.counter.get(); + self.counter.set(id + 1); + WebDriverMessageId(id) + } +} + fn extension_routes() -> Vec<(Method, &'static str, ServoExtensionRoute)> { vec![ ( @@ -145,10 +167,11 @@ pub struct WebDriverSession { unhandled_prompt_behavior: String, - // https://w3c.github.io/webdriver/#dfn-input-state-table - input_state_table: HashMap<String, InputSourceState>, - // https://w3c.github.io/webdriver/#dfn-input-cancel-list - input_cancel_list: Vec<ActionSequence>, + /// <https://w3c.github.io/webdriver/#dfn-input-state-map> + input_state_table: RefCell<HashMap<String, InputSourceState>>, + + /// <https://w3c.github.io/webdriver/#dfn-input-cancel-list> + input_cancel_list: RefCell<Vec<ActionSequence>>, } impl WebDriverSession { @@ -172,8 +195,8 @@ impl WebDriverSession { strict_file_interactability: false, unhandled_prompt_behavior: "dismiss and notify".to_string(), - input_state_table: HashMap::new(), - input_cancel_list: Vec::new(), + input_state_table: RefCell::new(HashMap::new()), + input_cancel_list: RefCell::new(Vec::new()), } } } @@ -187,8 +210,22 @@ struct Handler { /// for it to send us a load-status. Messages sent on it /// will be forwarded to the load_status_receiver. load_status_sender: IpcSender<WebDriverLoadStatus>, + session: Option<WebDriverSession>, + + /// The channel for sending Webdriver messages to the constellation. constellation_chan: Sender<EmbedderToConstellationMessage>, + + /// The IPC sender which we can clone and pass along to the constellation + constellation_sender: IpcSender<WebDriverCommandResponse>, + + /// Receiver notification from the constellation when a command is completed + constellation_receiver: IpcReceiver<WebDriverCommandResponse>, + + id_generator: WebDriverMessageIdGenerator, + + current_action_id: Cell<Option<WebDriverMessageId>>, + resize_timeout: u32, } @@ -409,11 +446,18 @@ impl Handler { let (load_status_sender, receiver) = ipc::channel().unwrap(); let (sender, load_status_receiver) = unbounded(); ROUTER.route_ipc_receiver_to_crossbeam_sender(receiver, sender); + + let (constellation_sender, constellation_receiver) = ipc::channel().unwrap(); + Handler { load_status_sender, load_status_receiver, session: None, constellation_chan, + constellation_sender, + constellation_receiver, + id_generator: WebDriverMessageIdGenerator::new(), + current_action_id: Cell::new(None), resize_timeout: 500, } } @@ -1445,18 +1489,13 @@ impl Handler { } fn handle_release_actions(&mut self) -> WebDriverResult<WebDriverResponse> { - let input_cancel_list = { - let session = self.session_mut()?; - session.input_cancel_list.reverse(); - mem::take(&mut session.input_cancel_list) - }; - + let input_cancel_list = self.session().unwrap().input_cancel_list.borrow(); if let Err(error) = self.dispatch_actions(&input_cancel_list) { return Err(WebDriverError::new(error, "")); } - let session = self.session_mut()?; - session.input_state_table = HashMap::new(); + let session = self.session()?; + session.input_state_table.borrow_mut().clear(); Ok(WebDriverResponse::Void) } @@ -1614,7 +1653,7 @@ impl Handler { let id = Uuid::new_v4().to_string(); // Step 8.1 - self.session_mut()?.input_state_table.insert( + self.session_mut()?.input_state_table.borrow_mut().insert( id.clone(), InputSourceState::Pointer(PointerInputState::new(&PointerType::Mouse)), ); @@ -1645,19 +1684,31 @@ impl Handler { ..Default::default() }; - // Step 8.16 Dispatch a list of actions with input state, - // actions, session's current browsing context, and actions options. - if let Err(error) = - self.dispatch_pointermove_action(&id, &pointer_move_action, 0) - { - return Err(WebDriverError::new(error, "")); - } + let action_sequence = ActionSequence { + id: id.clone(), + actions: ActionsType::Pointer { + parameters: PointerActionParameters { + pointer_type: PointerType::Mouse, + }, + actions: vec![ + PointerActionItem::Pointer(PointerAction::Move( + pointer_move_action, + )), + PointerActionItem::Pointer(PointerAction::Down( + pointer_down_action, + )), + PointerActionItem::Pointer(PointerAction::Up(pointer_up_action)), + ], + }, + }; - self.dispatch_pointerdown_action(&id, &pointer_down_action); - self.dispatch_pointerup_action(&id, &pointer_up_action); + let _ = self.dispatch_actions(&[action_sequence]); // Step 8.17 Remove an input source with input state and input id. - self.session_mut()?.input_state_table.remove(&id); + self.session_mut()? + .input_state_table + .borrow_mut() + .remove(&id); // Step 13 Ok(WebDriverResponse::Void) |