Implement MediaDevices.enumerateDevices()

This commit is contained in:
Fernando Jiménez Moreno 2020-07-02 17:35:51 +02:00
parent 9f26be6ac0
commit c0fb6c8d23
6 changed files with 159 additions and 14 deletions

24
Cargo.lock generated
View file

@ -5077,7 +5077,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-media" name = "servo-media"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"servo-media-audio", "servo-media-audio",
"servo-media-player", "servo-media-player",
@ -5089,7 +5089,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-media-audio" name = "servo-media-audio"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"boxfnonce", "boxfnonce",
"byte-slice-cast", "byte-slice-cast",
@ -5111,7 +5111,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-media-dummy" name = "servo-media-dummy"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"boxfnonce", "boxfnonce",
"ipc-channel", "ipc-channel",
@ -5126,7 +5126,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-media-gstreamer" name = "servo-media-gstreamer"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"boxfnonce", "boxfnonce",
"byte-slice-cast", "byte-slice-cast",
@ -5162,7 +5162,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-media-gstreamer-render" name = "servo-media-gstreamer-render"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"gstreamer", "gstreamer",
"gstreamer-video", "gstreamer-video",
@ -5172,7 +5172,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-media-gstreamer-render-android" name = "servo-media-gstreamer-render-android"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"glib", "glib",
"gstreamer", "gstreamer",
@ -5185,7 +5185,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-media-gstreamer-render-unix" name = "servo-media-gstreamer-render-unix"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"glib", "glib",
"gstreamer", "gstreamer",
@ -5198,7 +5198,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-media-player" name = "servo-media-player"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"ipc-channel", "ipc-channel",
"serde", "serde",
@ -5210,7 +5210,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-media-streams" name = "servo-media-streams"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"uuid", "uuid",
@ -5219,12 +5219,12 @@ dependencies = [
[[package]] [[package]]
name = "servo-media-traits" name = "servo-media-traits"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
[[package]] [[package]]
name = "servo-media-webrtc" name = "servo-media-webrtc"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"boxfnonce", "boxfnonce",
"lazy_static", "lazy_static",
@ -5302,7 +5302,7 @@ dependencies = [
[[package]] [[package]]
name = "servo_media_derive" name = "servo_media_derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/servo/media#eabe28e6df6170e4e36ef3d3fd48e1b592ef4964" source = "git+https://github.com/servo/media#7b0794d552207012131052be2da896e22174791b"
dependencies = [ dependencies = [
"proc-macro2 1.0.17", "proc-macro2 1.0.17",
"quote 1.0.2", "quote 1.0.2",

View file

@ -0,0 +1,85 @@
/* 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::codegen::Bindings::MediaDeviceInfoBinding::MediaDeviceInfoMethods;
use crate::dom::bindings::codegen::Bindings::MediaDeviceInfoBinding::MediaDeviceKind;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use servo_media::streams::device_monitor::MediaDeviceKind as ServoMediaDeviceKind;
#[dom_struct]
pub struct MediaDeviceInfo {
reflector_: Reflector,
device_id: DOMString,
kind: MediaDeviceKind,
label: DOMString,
group_id: DOMString,
}
impl MediaDeviceInfo {
fn new_inherited(
device_id: &str,
kind: MediaDeviceKind,
label: &str,
group_id: &str,
) -> MediaDeviceInfo {
MediaDeviceInfo {
reflector_: Reflector::new(),
device_id: DOMString::from(device_id),
kind,
label: DOMString::from(label),
group_id: DOMString::from(group_id),
}
}
pub fn new(
global: &GlobalScope,
device_id: &str,
kind: MediaDeviceKind,
label: &str,
group_id: &str,
) -> DomRoot<MediaDeviceInfo> {
reflect_dom_object(
Box::new(MediaDeviceInfo::new_inherited(
device_id, kind, label, group_id,
)),
global,
)
}
}
impl MediaDeviceInfoMethods for MediaDeviceInfo {
/// https://w3c.github.io/mediacapture-main/#dom-mediadeviceinfo-deviceid
fn DeviceId(&self) -> DOMString {
self.device_id.clone()
}
/// https://w3c.github.io/mediacapture-main/#dom-mediadeviceinfo-kind
fn Kind(&self) -> MediaDeviceKind {
self.kind
}
/// https://w3c.github.io/mediacapture-main/#dom-mediadeviceinfo-label
fn Label(&self) -> DOMString {
self.label.clone()
}
/// https://w3c.github.io/mediacapture-main/#dom-mediadeviceinfo-groupid
fn GroupId(&self) -> DOMString {
self.group_id.clone()
}
}
impl From<ServoMediaDeviceKind> for MediaDeviceKind {
fn from(kind: ServoMediaDeviceKind) -> MediaDeviceKind {
match kind {
ServoMediaDeviceKind::AudioInput => MediaDeviceKind::Audioinput,
ServoMediaDeviceKind::AudioOutput => MediaDeviceKind::Audiooutput,
ServoMediaDeviceKind::VideoInput => MediaDeviceKind::Videoinput,
}
}
}

View file

@ -12,10 +12,11 @@ use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::root::DomRoot;
use crate::dom::eventtarget::EventTarget; use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::mediadeviceinfo::MediaDeviceInfo;
use crate::dom::mediastream::MediaStream; use crate::dom::mediastream::MediaStream;
use crate::dom::mediastreamtrack::MediaStreamTrack; use crate::dom::mediastreamtrack::MediaStreamTrack;
use crate::dom::promise::Promise; use crate::dom::promise::Promise;
use crate::realms::InRealm; use crate::realms::{AlreadyInRealm, InRealm};
use dom_struct::dom_struct; use dom_struct::dom_struct;
use servo_media::streams::capture::{Constrain, ConstrainRange, MediaTrackConstraintSet}; use servo_media::streams::capture::{Constrain, ConstrainRange, MediaTrackConstraintSet};
use servo_media::streams::MediaStreamType; use servo_media::streams::MediaStreamType;
@ -62,6 +63,43 @@ impl MediaDevicesMethods for MediaDevices {
p.resolve_native(&stream); p.resolve_native(&stream);
p p
} }
/// https://w3c.github.io/mediacapture-main/#dom-mediadevices-enumeratedevices
fn EnumerateDevices(&self) -> Rc<Promise> {
// Step 1.
let global = self.global();
let in_realm_proof = AlreadyInRealm::assert(&global);
let p = Promise::new_in_current_realm(&global, InRealm::Already(&in_realm_proof));
// Step 2.
// XXX These steps should be run in parallel.
// XXX Steps 2.1 - 2.4
// Step 2.5
let media = ServoMedia::get().unwrap();
let device_monitor = media.get_device_monitor();
let result_list = match device_monitor.enumerate_devices() {
Ok(devices) => devices
.iter()
.map(|device| {
// XXX The media backend has no way to group devices yet.
MediaDeviceInfo::new(
&self.global(),
&device.device_id,
device.kind.into(),
&device.label,
"",
)
})
.collect(),
Err(_) => Vec::new(),
};
p.resolve_native(&result_list);
// Step 3.
p
}
} }
fn convert_constraints(js: &BooleanOrMediaTrackConstraints) -> Option<MediaTrackConstraintSet> { fn convert_constraints(js: &BooleanOrMediaTrackConstraints) -> Option<MediaTrackConstraintSet> {

View file

@ -425,6 +425,7 @@ pub mod imagedata;
pub mod inputevent; pub mod inputevent;
pub mod keyboardevent; pub mod keyboardevent;
pub mod location; pub mod location;
pub mod mediadeviceinfo;
pub mod mediadevices; pub mod mediadevices;
pub mod mediaelementaudiosourcenode; pub mod mediaelementaudiosourcenode;
pub mod mediaerror; pub mod mediaerror;

View file

@ -0,0 +1,21 @@
/* 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/. */
// https://w3c.github.io/mediacapture-main/#device-info
[Exposed=Window,
SecureContext, Pref="dom.webrtc.enabled"]
interface MediaDeviceInfo {
readonly attribute DOMString deviceId;
readonly attribute MediaDeviceKind kind;
readonly attribute DOMString label;
readonly attribute DOMString groupId;
[Default] object toJSON();
};
enum MediaDeviceKind {
"audioinput",
"audiooutput",
"videoinput"
};

View file

@ -8,7 +8,7 @@
SecureContext, Pref="dom.webrtc.enabled"] SecureContext, Pref="dom.webrtc.enabled"]
interface MediaDevices : EventTarget { interface MediaDevices : EventTarget {
// attribute EventHandler ondevicechange; // attribute EventHandler ondevicechange;
// Promise<sequence<MediaDeviceInfo>> enumerateDevices(); Promise<sequence<MediaDeviceInfo>> enumerateDevices();
}; };
partial interface Navigator { partial interface Navigator {