MediaSessionAction message from embedder to script thread

This commit is contained in:
Fernando Jiménez Moreno 2019-10-04 17:05:56 +02:00
parent 7101a9d070
commit 6233f78de4
5 changed files with 97 additions and 3 deletions

View file

@ -10,7 +10,7 @@ use euclid::Scale;
use gleam::gl;
use keyboard_types::KeyboardEvent;
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId, TraversalDirection};
use script_traits::{MouseButton, TouchEventType, TouchId, WheelDelta};
use script_traits::{MediaSessionActionType, MouseButton, TouchEventType, TouchId, WheelDelta};
use servo_geometry::DeviceIndependentPixel;
use servo_media::player::context::{GlApi, GlContext, NativeDisplay};
use servo_url::ServoUrl;
@ -102,6 +102,9 @@ pub enum WindowEvent {
CaptureWebRender,
/// Toggle sampling profiler with the given sampling rate and max duration.
ToggleSamplingProfiler(Duration, Duration),
/// Sent when the user triggers a media action through the UA exposed media UI
/// (play, pause, seek, etc.).
MediaSessionAction(TopLevelBrowsingContextId, MediaSessionActionType),
}
impl Debug for WindowEvent {
@ -132,6 +135,7 @@ impl Debug for WindowEvent {
WindowEvent::CaptureWebRender => write!(f, "CaptureWebRender"),
WindowEvent::ToggleSamplingProfiler(..) => write!(f, "ToggleSamplingProfiler"),
WindowEvent::ExitFullScreen(..) => write!(f, "ExitFullScreen"),
WindowEvent::MediaSessionAction(..) => write!(f, "MediaSessionAction"),
}
}
}

View file

@ -139,7 +139,6 @@ use net_traits::{self, FetchResponseMsg, IpcSend, ResourceThreads};
use profile_traits::mem;
use profile_traits::time;
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent};
use script_traits::MouseEventType;
use script_traits::{webdriver_msg, LogEntry, ScriptToConstellationChan, ServiceWorkerMsg};
use script_traits::{
AnimationState, AnimationTickType, AuxiliaryBrowsingContextLoadInfo, CompositorEvent,
@ -154,6 +153,7 @@ use script_traits::{
};
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
use script_traits::{MessagePortMsg, PortMessageTask, StructuredSerializedData};
use script_traits::{MediaSessionActionType, MouseEventType};
use script_traits::{SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WebDriverCommandMsg};
use serde::{Deserialize, Serialize};
use servo_config::{opts, pref};
@ -1541,6 +1541,9 @@ where
FromCompositorMsg::ExitFullScreen(top_level_browsing_context_id) => {
self.handle_exit_fullscreen_msg(top_level_browsing_context_id);
},
FromCompositorMsg::MediaSessionAction(top_level_browsing_context_id, action) => {
self.handle_media_session_action_msg(top_level_browsing_context_id, action);
},
}
}
@ -5019,4 +5022,35 @@ where
.send(ToCompositorMsg::SetFrameTree(frame_tree));
}
}
fn handle_media_session_action_msg(
&mut self,
top_level_browsing_context_id: TopLevelBrowsingContextId,
action: MediaSessionActionType,
) {
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
Some(browsing_context) => browsing_context.pipeline_id,
None => {
return warn!(
"Browsing context {} got media session action request after closure.",
browsing_context_id
);
},
};
let msg =
ConstellationControlMsg::MediaSessionAction(top_level_browsing_context_id, action);
let result = match self.pipelines.get(&pipeline_id) {
None => {
return warn!(
"Pipeline {} got media session action request after closure.",
pipeline_id
)
},
Some(pipeline) => pipeline.event_loop.send(msg),
};
if let Err(e) = result {
self.handle_send_error(pipeline_id, e);
}
}
}

View file

@ -139,7 +139,7 @@ use script_traits::{
DiscardBrowsingContext, DocumentActivity, EventResult, HistoryEntryReplacement,
};
use script_traits::{InitialScriptState, JsEvalResult, LayoutMsg, LoadData, LoadOrigin};
use script_traits::{MouseButton, MouseEventType, NewLayoutInfo};
use script_traits::{MediaSessionActionType, MouseButton, MouseEventType, NewLayoutInfo};
use script_traits::{Painter, ProgressiveWebMetricType, ScriptMsg, ScriptThreadFactory};
use script_traits::{ScriptToConstellationChan, TimerEvent, TimerSchedulerMsg};
use script_traits::{TimerSource, TouchEventType, TouchId, UntrustedNodeAddress, WheelDelta};
@ -1720,6 +1720,7 @@ impl ScriptThread {
WebVREvents(id, ..) => Some(id),
PaintMetric(..) => None,
ExitFullScreen(id, ..) => Some(id),
MediaSessionAction(..) => None,
}
},
MixedMessage::FromDevtools(_) => None,
@ -1949,6 +1950,9 @@ impl ScriptThread {
ConstellationControlMsg::PaintMetric(pipeline_id, metric_type, metric_value) => {
self.handle_paint_metric(pipeline_id, metric_type, metric_value)
},
ConstellationControlMsg::MediaSessionAction(browsing_context_id, action) => {
self.handle_media_session_action(browsing_context_id, action)
},
msg @ ConstellationControlMsg::AttachLayout(..) |
msg @ ConstellationControlMsg::Viewport(..) |
msg @ ConstellationControlMsg::SetScrollState(..) |
@ -3932,6 +3936,14 @@ impl ScriptThread {
}
}
fn handle_media_session_action(
&self,
browsing_context_id: TopLevelBrowsingContextId,
action: MediaSessionActionType,
) {
// TODO
}
pub fn enqueue_microtask(job: Microtask) {
SCRIPT_THREAD_ROOT.with(|root| {
let script_thread = unsafe { &*root.get().unwrap() };

View file

@ -388,6 +388,8 @@ pub enum ConstellationControlMsg {
WebVREvents(PipelineId, Vec<WebVREvent>),
/// Notifies the script thread about a new recorded paint metric.
PaintMetric(PipelineId, ProgressiveWebMetricType, u64),
/// Notifies the media session about a user requested media session action.
MediaSessionAction(TopLevelBrowsingContextId, MediaSessionActionType),
}
impl fmt::Debug for ConstellationControlMsg {
@ -426,6 +428,7 @@ impl fmt::Debug for ConstellationControlMsg {
WebVREvents(..) => "WebVREvents",
PaintMetric(..) => "PaintMetric",
ExitFullScreen(..) => "ExitFullScreen",
MediaSessionAction(..) => "MediaSessionAction",
};
write!(formatter, "ConstellationControlMsg::{}", variant)
}
@ -877,6 +880,8 @@ pub enum ConstellationMsg {
DisableProfiler,
/// Request to exit from fullscreen mode
ExitFullScreen(TopLevelBrowsingContextId),
/// Media session action.
MediaSessionAction(TopLevelBrowsingContextId, MediaSessionActionType),
}
impl fmt::Debug for ConstellationMsg {
@ -907,6 +912,7 @@ impl fmt::Debug for ConstellationMsg {
EnableProfiler(..) => "EnableProfiler",
DisableProfiler => "DisableProfiler",
ExitFullScreen(..) => "ExitFullScreen",
MediaSessionAction(..) => "MediaSessionAction",
};
write!(formatter, "ConstellationMsg::{}", variant)
}
@ -1052,4 +1058,32 @@ pub enum MessagePortMsg {
RemoveMessagePort(MessagePortId),
/// Handle a new port-message-task.
NewTask(MessagePortId, PortMessageTask),
/// The type of MediaSession action.
/// https://w3c.github.io/mediasession/#enumdef-mediasessionaction
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum MediaSessionActionType {
/// The action intent is to resume playback.
Play,
/// The action intent is to pause the currently active playback.
Pause,
/// The action intent is to move the playback time backward by a short period (i.e. a few
/// seconds).
SeekBackward,
/// The action intent is to move the playback time forward by a short period (i.e. a few
/// seconds).
SeekForward,
/// The action intent is to either start the current playback from the beginning if the
/// playback has a notion, of beginning, or move to the previous item in the playlist if the
/// playback has a notion of playlist.
PreviousTrack,
/// The action is to move to the playback to the next item in the playlist if the playback has
/// a notion of playlist.
NextTrack,
/// The action intent is to skip the advertisement that is currently playing.
SkipAd,
/// The action intent is to stop the playback and clear the state if appropriate.
Stop,
/// The action intent is to move the playback time to a specific time.
SeekTo,
}

View file

@ -713,6 +713,16 @@ where
);
}
},
WindowEvent::MediaSessionAction(ctx, a) => {
let msg = ConstellationMsg::MediaSessionAction(ctx, a);
if let Err(e) = self.constellation_chan.send(msg) {
warn!(
"Sending MediaSessionAction message to constellation failed ({:?}).",
e
);
}
},
}
}