MediaSession API DOM bindings

This commit is contained in:
Fernando Jiménez Moreno 2019-10-01 13:25:16 +02:00
parent 7da8d75a7e
commit 4b5b4d19bf
6 changed files with 262 additions and 0 deletions

View file

@ -0,0 +1,94 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::MediaMetadataBinding;
use crate::dom::bindings::codegen::Bindings::MediaMetadataBinding::MediaMetadataInit;
use crate::dom::bindings::codegen::Bindings::MediaMetadataBinding::MediaMetadataMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::mediasession::MediaSession;
use crate::dom::window::Window;
use dom_struct::dom_struct;
#[dom_struct]
pub struct MediaMetadata {
reflector_: Reflector,
session: MutNullableDom<MediaSession>,
title: DomRefCell<DOMString>,
artist: DomRefCell<DOMString>,
album: DomRefCell<DOMString>,
}
impl MediaMetadata {
fn new_inherited(init: &MediaMetadataInit) -> MediaMetadata {
MediaMetadata {
reflector_: Reflector::new(),
// TODO(ferjm): Set active media session?
session: Default::default(),
title: DomRefCell::new(init.title.clone()),
artist: DomRefCell::new(init.artist.clone()),
album: DomRefCell::new(init.album.clone()),
}
}
pub fn new(global: &Window, init: &MediaMetadataInit) -> DomRoot<MediaMetadata> {
reflect_dom_object(
Box::new(MediaMetadata::new_inherited(init)),
global,
MediaMetadataBinding::Wrap,
)
}
/// https://w3c.github.io/mediasession/#dom-mediametadata-mediametadata
pub fn Constructor(
window: &Window,
init: &MediaMetadataInit,
) -> Fallible<DomRoot<MediaMetadata>> {
Ok(MediaMetadata::new(window, init))
}
fn queue_update_metadata_algorithm(&self) {
if self.session.get().is_none() {
return;
}
}
}
impl MediaMetadataMethods for MediaMetadata {
/// https://w3c.github.io/mediasession/#dom-mediametadata-title
fn Title(&self) -> DOMString {
self.title.borrow().clone()
}
/// https://w3c.github.io/mediasession/#dom-mediametadata-title
fn SetTitle(&self, value: DOMString) -> () {
*self.title.borrow_mut() = value;
self.queue_update_metadata_algorithm();
}
/// https://w3c.github.io/mediasession/#dom-mediametadata-artist
fn Artist(&self) -> DOMString {
self.artist.borrow().clone()
}
/// https://w3c.github.io/mediasession/#dom-mediametadata-artist
fn SetArtist(&self, value: DOMString) -> () {
*self.artist.borrow_mut() = value;
self.queue_update_metadata_algorithm();
}
/// https://w3c.github.io/mediasession/#dom-mediametadata-album
fn Album(&self) -> DOMString {
self.album.borrow().clone()
}
/// https://w3c.github.io/mediasession/#dom-mediametadata-album
fn SetAlbum(&self, value: DOMString) -> () {
*self.album.borrow_mut() = value;
self.queue_update_metadata_algorithm();
}
}

View file

@ -0,0 +1,70 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding;
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding::MediaSessionAction;
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding::MediaSessionActionHandler;
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding::MediaSessionMethods;
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding::MediaSessionPlaybackState;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::mediametadata::MediaMetadata;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use std::rc::Rc;
#[dom_struct]
pub struct MediaSession {
reflector_: Reflector,
/// https://w3c.github.io/mediasession/#dom-mediasession-metadata
metadata: MutNullableDom<MediaMetadata>,
/// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate
playback_state: DomRefCell<MediaSessionPlaybackState>,
}
impl MediaSession {
fn new_inherited() -> MediaSession {
MediaSession {
reflector_: Reflector::new(),
metadata: Default::default(),
playback_state: DomRefCell::new(MediaSessionPlaybackState::None),
}
}
pub fn new(global: &Window) -> DomRoot<MediaSession> {
reflect_dom_object(
Box::new(MediaSession::new_inherited()),
global,
MediaSessionBinding::Wrap,
)
}
}
impl MediaSessionMethods for MediaSession {
fn GetMetadata(&self) -> Option<DomRoot<MediaMetadata>> {
self.metadata.get()
}
fn SetMetadata(&self, value: Option<&MediaMetadata>) {
self.metadata.set(value);
}
/// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate
fn PlaybackState(&self) -> MediaSessionPlaybackState {
*self.playback_state.borrow()
}
/// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate
fn SetPlaybackState(&self, value: MediaSessionPlaybackState) {
*self.playback_state.borrow_mut() = value;
}
fn SetActionHandler(
&self,
_action: MediaSessionAction,
_handler: Option<Rc<MediaSessionActionHandler>>,
) {
}
}

View file

@ -398,8 +398,10 @@ pub mod mediaelementaudiosourcenode;
pub mod mediaerror;
pub mod mediafragmentparser;
pub mod medialist;
pub mod mediametadata;
pub mod mediaquerylist;
pub mod mediaquerylistevent;
pub mod mediasession;
pub mod mediastream;
pub mod mediastreamtrack;
pub mod messagechannel;

View file

@ -12,6 +12,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::bluetooth::Bluetooth;
use crate::dom::gamepadlist::GamepadList;
use crate::dom::mediadevices::MediaDevices;
use crate::dom::mediasession::MediaSession;
use crate::dom::mimetypearray::MimeTypeArray;
use crate::dom::navigatorinfo;
use crate::dom::permissions::Permissions;
@ -34,6 +35,7 @@ pub struct Navigator {
mediadevices: MutNullableDom<MediaDevices>,
gamepads: MutNullableDom<GamepadList>,
permissions: MutNullableDom<Permissions>,
mediasession: MutNullableDom<MediaSession>,
}
impl Navigator {
@ -48,6 +50,7 @@ impl Navigator {
mediadevices: Default::default(),
gamepads: Default::default(),
permissions: Default::default(),
mediasession: Default::default(),
}
}
@ -186,4 +189,10 @@ impl NavigatorMethods for Navigator {
self.mediadevices
.or_init(|| MediaDevices::new(&self.global()))
}
/// https://w3c.github.io/mediasession/#dom-navigator-mediasession
fn MediaSession(&self) -> DomRoot<MediaSession> {
self.mediasession
.or_init(|| MediaSession::new(self.global().as_window()))
}
}

View file

@ -0,0 +1,30 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/*
* The origin of this IDL file is
* https://w3c.github.io/mediasession/#mediametadata
*/
dictionary MediaImage {
required USVString src;
DOMString sizes = "";
DOMString type = "";
};
[Exposed=Window,
Constructor(optional MediaMetadataInit init = {})]
interface MediaMetadata {
attribute DOMString title;
attribute DOMString artist;
attribute DOMString album;
// TODO: https://github.com/servo/servo/issues/10072
// attribute FrozenArray<MediaImage> artwork;
};
dictionary MediaMetadataInit {
DOMString title = "";
DOMString artist = "";
DOMString album = "";
sequence<MediaImage> artwork = [];
};

View file

@ -0,0 +1,57 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/*
* The origin of this IDL file is
* https://w3c.github.io/mediasession/#mediasession
*/
[Exposed=Window]
partial interface Navigator {
[SameObject] readonly attribute MediaSession mediaSession;
};
enum MediaSessionPlaybackState {
"none",
"paused",
"playing"
};
enum MediaSessionAction {
"play",
"pause",
"seekbackward",
"seekforward",
"previoustrack",
"nexttrack",
"skipad",
"stop",
"seekto"
};
dictionary MediaSessionActionDetails {
required MediaSessionAction action;
};
dictionary MediaSessionSeekActionDetails : MediaSessionActionDetails {
double? seekOffset;
};
dictionary MediaSessionSeekToActionDetails : MediaSessionActionDetails {
required double seekTime;
boolean? fastSeek;
};
callback MediaSessionActionHandler = void(MediaSessionActionDetails details);
[Exposed=Window]
interface MediaSession {
attribute MediaMetadata? metadata;
attribute MediaSessionPlaybackState playbackState;
void setActionHandler(MediaSessionAction action, MediaSessionActionHandler? handler);
//void setPositionState(optional MediaPositionState? state);
};