diff --git a/components/embedder_traits/lib.rs b/components/embedder_traits/lib.rs index f65ed514f4db..9d4e56dd297d 100644 --- a/components/embedder_traits/lib.rs +++ b/components/embedder_traits/lib.rs @@ -213,9 +213,19 @@ pub struct MediaMetadata { /// Title pub title: String, /// Artist - pub artist: Option, + pub artist: String, /// Album - pub album: Option, + pub album: String, +} + +impl MediaMetadata { + pub fn new(title: String) -> Self { + Self { + title, + artist: "".to_owned(), + album: "".to_owned(), + } + } } /// https://w3c.github.io/mediasession/#enumdef-mediasessionplaybackstate diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 333412ed3cdf..f8f707a0dd9c 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -67,7 +67,7 @@ use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; use dom_struct::dom_struct; use embedder_traits::resources::{self, Resource as EmbedderResource}; -use embedder_traits::{MediaMetadata, MediaSessionEvent, MediaSessionPlaybackState}; +use embedder_traits::{MediaSessionEvent, MediaSessionPlaybackState}; use euclid::default::Size2D; use headers::{ContentLength, ContentRange, HeaderMapExt}; use html5ever::{LocalName, Prefix}; @@ -1731,15 +1731,13 @@ impl HTMLMediaElement { let global = self.global(); let window = global.as_window(); - // Send a media session event with the obtained metadata. - self.send_media_session_event(MediaSessionEvent::SetMetadata(MediaMetadata { - title: metadata + // Update the media session metadata title with the obtained metadata. + window.Navigator().MediaSession().update_title( + metadata .title .clone() .unwrap_or(window.get_url().into_string()), - artist: None, - album: None, - })); + ); }, PlayerEvent::NeedData => { // The player needs more data. diff --git a/components/script/dom/mediametadata.rs b/components/script/dom/mediametadata.rs index db84df878c5a..f2e94abfaa17 100644 --- a/components/script/dom/mediametadata.rs +++ b/components/script/dom/mediametadata.rs @@ -68,7 +68,7 @@ impl MediaMetadataMethods for MediaMetadata { } /// https://w3c.github.io/mediasession/#dom-mediametadata-title - fn SetTitle(&self, value: DOMString) -> () { + fn SetTitle(&self, value: DOMString) { *self.title.borrow_mut() = value; self.queue_update_metadata_algorithm(); } @@ -79,7 +79,7 @@ impl MediaMetadataMethods for MediaMetadata { } /// https://w3c.github.io/mediasession/#dom-mediametadata-artist - fn SetArtist(&self, value: DOMString) -> () { + fn SetArtist(&self, value: DOMString) { *self.artist.borrow_mut() = value; self.queue_update_metadata_algorithm(); } @@ -90,7 +90,7 @@ impl MediaMetadataMethods for MediaMetadata { } /// https://w3c.github.io/mediasession/#dom-mediametadata-album - fn SetAlbum(&self, value: DOMString) -> () { + fn SetAlbum(&self, value: DOMString) { *self.album.borrow_mut() = value; self.queue_update_metadata_algorithm(); } diff --git a/components/script/dom/mediasession.rs b/components/script/dom/mediasession.rs index 250f420df60d..1523e9a0ae60 100644 --- a/components/script/dom/mediasession.rs +++ b/components/script/dom/mediasession.rs @@ -100,13 +100,6 @@ impl MediaSession { } pub fn send_event(&self, event: MediaSessionEvent) { - match event { - MediaSessionEvent::SetMetadata(ref metadata) => { - *self.metadata.borrow_mut() = Some(metadata.clone()); - }, - _ => (), - } - let global = self.global(); let window = global.as_window(); let pipeline_id = window @@ -114,6 +107,23 @@ impl MediaSession { .expect("Cannot send media session event outside of a pipeline"); window.send_to_constellation(ScriptMsg::MediaSessionEvent(pipeline_id, event)); } + + pub fn update_title(&self, title: String) { + let mut metadata = self.metadata.borrow_mut(); + if let Some(ref mut metadata) = *metadata { + // We only update the title with the data provided by the media + // player and iff the user did not provide a title. + if !metadata.title.is_empty() { + return; + } + metadata.title = title; + } else { + *metadata = Some(EmbedderMediaMetadata::new(title)); + } + self.send_event(MediaSessionEvent::SetMetadata( + metadata.as_ref().unwrap().clone(), + )); + } } impl MediaSessionMethods for MediaSession { @@ -122,8 +132,8 @@ impl MediaSessionMethods for MediaSession { if let Some(ref metadata) = *self.metadata.borrow() { let mut init = MediaMetadataInit::empty(); init.title = DOMString::from_string(metadata.title.clone()); - init.artist = DOMString::from_string(metadata.artist.clone().unwrap_or("".to_owned())); - init.album = DOMString::from_string(metadata.album.clone().unwrap_or("".to_owned())); + init.artist = DOMString::from_string(metadata.artist.clone()); + init.album = DOMString::from_string(metadata.album.clone()); let global = self.global(); Some(MediaMetadata::new(&global.as_window(), &init)) } else { @@ -137,12 +147,27 @@ impl MediaSessionMethods for MediaSession { metadata.set_session(self); } - let _metadata = metadata.map(|m| EmbedderMediaMetadata { - title: m.Title().into(), - artist: Some(m.Artist().into()), - album: Some(m.Album().into()), - }); - *self.metadata.borrow_mut() = _metadata; + let global = self.global(); + let window = global.as_window(); + let _metadata = match metadata { + Some(m) => { + let title = if m.Title().is_empty() { + window.get_url().into_string() + } else { + m.Title().into() + }; + EmbedderMediaMetadata { + title, + artist: m.Artist().into(), + album: m.Album().into(), + } + }, + None => EmbedderMediaMetadata::new(window.get_url().into_string()), + }; + + *self.metadata.borrow_mut() = Some(_metadata.clone()); + + self.send_event(MediaSessionEvent::SetMetadata(_metadata)); } /// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 554cf7ee67cf..c7986e05623b 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -586,8 +586,8 @@ impl ServoGlue { MediaSessionEvent::SetMetadata(metadata) => { self.callbacks.host_callbacks.on_media_session_metadata( metadata.title, - metadata.artist.unwrap_or("".to_owned()), - metadata.album.unwrap_or("".to_owned()), + metadata.artist, + metadata.album, ) }, MediaSessionEvent::PlaybackStateChange(state) => self