Commit dbbe70b8 authored by zqzhang's avatar zqzhang Committed by Commit bot

Make MediaSession per frame as an attribute of Navigator

This CL makes MediaSession non user-constructible, and make it as
an attribute of window.navigator, thus MediaSession is one object
per frame. This CL also adds back the removed browser tests as
layout tests using a mock blink::mojom::MediaSessionService in js.
This CL also made MediaSession enabled in tests so no need for
virtual tests anymore.

Spec URL: https://wicg.github.io/mediasession/

BUG=643190,646490,653894

Review-Url: https://codereview.chromium.org/2401013002
Cr-Commit-Position: refs/heads/master@{#424702}
parent 0b40dcf1
...@@ -172,11 +172,6 @@ ...@@ -172,11 +172,6 @@
"base": "fast/events/touch/gesture", "base": "fast/events/touch/gesture",
"args": ["--enable-smooth-scrolling"] "args": ["--enable-smooth-scrolling"]
}, },
{
"prefix": "mediasession",
"base": "media/mediasession",
"args": ["--enable-blink-features=MediaSession"]
},
{ {
"prefix": "mse-1mb-buffers", "prefix": "mse-1mb-buffers",
"base": "http/tests/media/media-source/stream_memory_tests", "base": "http/tests/media/media-source/stream_memory_tests",
......
...@@ -48,6 +48,7 @@ PASS window.cached_navigator.vendorSub is '' ...@@ -48,6 +48,7 @@ PASS window.cached_navigator.vendorSub is ''
PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.onchange is null
PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_connection.ontypechange is null
PASS window.cached_navigator_mediaDevices.ondevicechange is null PASS window.cached_navigator_mediaDevices.ondevicechange is null
PASS window.cached_navigator_mediaSession.metadata is null
PASS window.cached_navigator_presentation.defaultRequest is null PASS window.cached_navigator_presentation.defaultRequest is null
PASS window.cached_navigator_serviceWorker.controller is null PASS window.cached_navigator_serviceWorker.controller is null
PASS window.cached_navigator_serviceWorker.oncontrollerchange is null PASS window.cached_navigator_serviceWorker.oncontrollerchange is null
......
...@@ -48,6 +48,7 @@ PASS window.cached_navigator.vendorSub is '' ...@@ -48,6 +48,7 @@ PASS window.cached_navigator.vendorSub is ''
PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.onchange is null
PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_connection.ontypechange is null
PASS window.cached_navigator_mediaDevices.ondevicechange is null PASS window.cached_navigator_mediaDevices.ondevicechange is null
PASS window.cached_navigator_mediaSession.metadata is null
PASS window.cached_navigator_presentation.defaultRequest is null PASS window.cached_navigator_presentation.defaultRequest is null
PASS window.cached_navigator_serviceWorker.controller is null PASS window.cached_navigator_serviceWorker.controller is null
PASS window.cached_navigator_serviceWorker.oncontrollerchange is null PASS window.cached_navigator_serviceWorker.oncontrollerchange is null
......
...@@ -48,6 +48,7 @@ PASS window.cached_navigator.vendorSub is '' ...@@ -48,6 +48,7 @@ PASS window.cached_navigator.vendorSub is ''
PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.onchange is null
PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_connection.ontypechange is null
PASS window.cached_navigator_mediaDevices.ondevicechange is null PASS window.cached_navigator_mediaDevices.ondevicechange is null
PASS window.cached_navigator_mediaSession.metadata is null
PASS window.cached_navigator_presentation.defaultRequest is null PASS window.cached_navigator_presentation.defaultRequest is null
PASS window.cached_navigator_serviceWorker.controller is null PASS window.cached_navigator_serviceWorker.controller is null
PASS window.cached_navigator_serviceWorker.oncontrollerchange is null PASS window.cached_navigator_serviceWorker.oncontrollerchange is null
......
...@@ -53,6 +53,7 @@ PASS oldChildWindow.navigator.hardwareConcurrency is newChildWindow.navigator.ha ...@@ -53,6 +53,7 @@ PASS oldChildWindow.navigator.hardwareConcurrency is newChildWindow.navigator.ha
PASS oldChildWindow.navigator.language is newChildWindow.navigator.language PASS oldChildWindow.navigator.language is newChildWindow.navigator.language
PASS oldChildWindow.navigator.maxTouchPoints is newChildWindow.navigator.maxTouchPoints PASS oldChildWindow.navigator.maxTouchPoints is newChildWindow.navigator.maxTouchPoints
PASS oldChildWindow.navigator.mediaDevices.ondevicechange is newChildWindow.navigator.mediaDevices.ondevicechange PASS oldChildWindow.navigator.mediaDevices.ondevicechange is newChildWindow.navigator.mediaDevices.ondevicechange
PASS oldChildWindow.navigator.mediaSession.metadata is newChildWindow.navigator.mediaSession.metadata
PASS oldChildWindow.navigator.onLine is newChildWindow.navigator.onLine PASS oldChildWindow.navigator.onLine is newChildWindow.navigator.onLine
PASS oldChildWindow.navigator.platform is newChildWindow.navigator.platform PASS oldChildWindow.navigator.platform is newChildWindow.navigator.platform
PASS oldChildWindow.navigator.presentation.defaultRequest is newChildWindow.navigator.presentation.defaultRequest PASS oldChildWindow.navigator.presentation.defaultRequest is newChildWindow.navigator.presentation.defaultRequest
......
...@@ -53,6 +53,7 @@ PASS childWindow.navigator.hardwareConcurrency is window.navigator.hardwareConcu ...@@ -53,6 +53,7 @@ PASS childWindow.navigator.hardwareConcurrency is window.navigator.hardwareConcu
PASS childWindow.navigator.language is window.navigator.language PASS childWindow.navigator.language is window.navigator.language
PASS childWindow.navigator.maxTouchPoints is 0 PASS childWindow.navigator.maxTouchPoints is 0
PASS childWindow.navigator.mediaDevices.ondevicechange is null PASS childWindow.navigator.mediaDevices.ondevicechange is null
PASS childWindow.navigator.mediaSession.metadata is null
PASS childWindow.navigator.onLine is window.navigator.onLine PASS childWindow.navigator.onLine is window.navigator.onLine
PASS childWindow.navigator.platform is window.navigator.platform PASS childWindow.navigator.platform is window.navigator.platform
FAIL childWindow.navigator.presentation.defaultRequest should be null. Threw exception TypeError: Cannot read property 'defaultRequest' of null FAIL childWindow.navigator.presentation.defaultRequest should be null. Threw exception TypeError: Cannot read property 'defaultRequest' of null
......
...@@ -52,6 +52,7 @@ PASS childWindow.navigator.hardwareConcurrency is window.navigator.hardwareConcu ...@@ -52,6 +52,7 @@ PASS childWindow.navigator.hardwareConcurrency is window.navigator.hardwareConcu
PASS childWindow.navigator.language is window.navigator.language PASS childWindow.navigator.language is window.navigator.language
PASS childWindow.navigator.maxTouchPoints is 0 PASS childWindow.navigator.maxTouchPoints is 0
PASS childWindow.navigator.mediaDevices.ondevicechange is null PASS childWindow.navigator.mediaDevices.ondevicechange is null
PASS childWindow.navigator.mediaSession.metadata is null
PASS childWindow.navigator.onLine is window.navigator.onLine PASS childWindow.navigator.onLine is window.navigator.onLine
PASS childWindow.navigator.platform is window.navigator.platform PASS childWindow.navigator.platform is window.navigator.platform
FAIL childWindow.navigator.presentation.defaultRequest should be null. Threw exception TypeError: Cannot read property 'defaultRequest' of null FAIL childWindow.navigator.presentation.defaultRequest should be null. Threw exception TypeError: Cannot read property 'defaultRequest' of null
......
CONSOLE WARNING: line 6: dummy log entry to avoid an empty -expected.txt in virtual/
This is a testharness.js-based test.
FAIL Test that MediaImage is constructed using a dictionary MediaImage is not defined
FAIL Test the different values allowed in MediaImage init dictionary MediaImage is not defined
FAIL Test the default values for MediaImage MediaImage is not defined
FAIL Test that passing unknown values to the dictionary is a no-op MediaMetadata is not defined
Harness: the test ran to completion.
...@@ -3,11 +3,9 @@ ...@@ -3,11 +3,9 @@
<script src="../../resources/testharness.js"></script> <script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="../../resources/testharnessreport.js"></script>
<script> <script>
console.warn("dummy log entry to avoid an empty -expected.txt in virtual/");
test(function() { test(function() {
var image = new MediaImage({}); var image = new MediaImage({});
assert_true(image != null); assert_not_equals(image, null);
var exception = false; var exception = false;
try { try {
......
This is a testharness.js-based test.
FAIL MediaSession() constructor assert_true: Run either manually by passing the MediaSession flag or as part of the virtual mediasession testsuite. expected true got false
Harness: the test ran to completion.
<!DOCTYPE html>
<title>MediaSession() constructor</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
test(function() {
assert_true(!window.internals || window.internals.runtimeFlags.mediaSessionEnabled,
"Run either manually by passing the MediaSession flag or as part of the virtual mediasession testsuite.");
console.warn("dummy log entry to avoid an empty -expected.txt in virtual/");
var mediaSession = new MediaSession();
assert_true(mediaSession instanceof MediaSession);
});
</script>
CONSOLE WARNING: line 6: dummy log entry to avoid an empty -expected.txt in virtual/
This is a testharness.js-based test.
FAIL Test that MediaMetadata is constructed using a dictionary MediaMetadata is not defined
FAIL Test the different values allowed in MediaMetadata init dictionary MediaMetadata is not defined
FAIL Test the default values for MediaMetadata MediaMetadata is not defined
FAIL Test that passing unknown values to the dictionary is a no-op MediaMetadata is not defined
Harness: the test ran to completion.
...@@ -3,11 +3,10 @@ ...@@ -3,11 +3,10 @@
<script src="../../resources/testharness.js"></script> <script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="../../resources/testharnessreport.js"></script>
<script> <script>
console.warn("dummy log entry to avoid an empty -expected.txt in virtual/");
test(function() { test(function() {
var metadata = new MediaMetadata({}); var metadata = new MediaMetadata({});
assert_true(metadata != null); assert_not_equals(metadata, null);
var exception = false; var exception = false;
try { try {
...@@ -22,7 +21,7 @@ ...@@ -22,7 +21,7 @@
metadata = new MediaMetadata(42); metadata = new MediaMetadata(42);
} catch (e) { } catch (e) {
exception = true; exception = true;
} }
assert_true(exception); assert_true(exception);
}, 'Test that MediaMetadata is constructed using a dictionary'); }, 'Test that MediaMetadata is constructed using a dictionary');
......
<!DOCTYPE html>
<title>MediaSession Mojo Test</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/mojo-helpers.js"></script>
<script src="resources/mediasessionservice-mock.js"></script>
<script src="resources/utils.js"></script>
<script>
async_test(function(t) {
mediaSessionServiceMock.then(m => {
var metadata = new MediaMetadata({
artwork: [
{ src: "file:///foo/bar.jpg", type: "image/jpeg"}
]});
var expectedMetadata = new MediaMetadata({});
m.setMetadataCallback(t.step_func(function(receivedMetadata) {
assert_metadata_equals(expectedMetadata, receivedMetadata);
t.done();
}));
window.navigator.mediaSession.metadata = metadata;
});
}, "test that null MediaMetadata is correctly propagated");
</script>
<!DOCTYPE html>
<title>MediaSession Mojo Test</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/mojo-helpers.js"></script>
<script src="resources/mediasessionservice-mock.js"></script>
<script src="resources/utils.js"></script>
<script>
async_test(function(t) {
mediaSessionServiceMock.then(m => {
var dontCareMetadata = new MediaMetadata({});
m.setMetadataCallback(t.step_func(function() {
var metadata = new MediaMetadata({
title: "title2",
artist: "artist2",
album: "album2",
artwork: [
{ src: "http://foo.com/bar.jpg", type: "image/jpeg", sizes: "256x256"}
]});
m.setMetadataCallback(t.step_func(function(receivedMetadata) {
assert_metadata_equals(metadata, receivedMetadata);
t.done();
}));
window.navigator.mediaSession.metadata = metadata;
}));
window.navigator.mediaSession.metadata = dontCareMetadata;
});
}, "test that MediaMetadata is correctly propagated twice");
</script>
<!DOCTYPE html>
<title>MediaSession Mojo Test</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/mojo-helpers.js"></script>
<script src="resources/mediasessionservice-mock.js"></script>
<script src="resources/utils.js"></script>
<script>
async_test(function(t) {
mediaSessionServiceMock.then(m => {
var metadata = new MediaMetadata({
title: "title1",
artist: "artist1",
album: "album1",
artwork: [
{ src: "http://foo.com/bar.png", type: "image/png", sizes: "128x128" }
]});
m.setMetadataCallback(t.step_func(function(receivedMetadata) {
assert_metadata_equals(metadata, receivedMetadata);
t.done();
}));
window.navigator.mediaSession.metadata = metadata;
});
}, "test that MediaMetadata is correctly propagated");
</script>
/*
* mediasessionservice-mock contains a mock implementation of MediaSessionService.
*/
"use strict";
function mojoString16ToJS(mojoString16) {
return String.fromCharCode.apply(null, mojoString16.data);
}
function mojoImageToJS(mojoImage) {
var src = mojoImage.src.url;
var type = mojoString16ToJS(mojoImage.type);
var sizes = "";
for (var i = 0; i < mojoImage.sizes.length; i++) {
if (i > 0)
sizes += " ";
var mojoSize = mojoImage.sizes[i];
sizes += mojoSize.width.toString() + "x" + mojoSize.height.toString();
}
return { src: src, type: type, sizes: sizes };
}
function mojoMetadataToJS(mojoMetadata) {
if (mojoMetadata == null)
return null;
var title = mojoString16ToJS(mojoMetadata.title);
var artist = mojoString16ToJS(mojoMetadata.artist);
var album = mojoString16ToJS(mojoMetadata.album);
var artwork = [];
for (var i = 0; i < mojoMetadata.artwork.length; i++)
artwork.push(mojoImageToJS(mojoMetadata.artwork[i]));
return new MediaMetadata({title: title, artist: artist, album: album, artwork: artwork});
}
let mediaSessionServiceMock = loadMojoModules(
'mediaSessionServiceMock',
['third_party/WebKit/public/platform/modules/mediasession/media_session.mojom',
'mojo/public/js/router',
]).then(mojo => {
let [mediaSessionService, router] = mojo.modules;
class MediaSessionServiceMock {
constructor(interfaceProvider) {
interfaceProvider.addInterfaceOverrideForTesting(
mediaSessionService.MediaSessionService.name,
handle => this.connectMediaSessionService_(handle));
this.interfaceProvider_ = interfaceProvider;
this.pendingResponse_ = null;
}
connectMediaSessionService_(handle) {
this.mediaSessionServiceStub_ = new mediaSessionService.MediaSessionService.stubClass(this);
this.mediaSessionServiceRouter_ = new router.Router(handle);
this.mediaSessionServiceRouter_.setIncomingReceiver(this.mediaSessionServiceStub_);
}
setMetadata(metadata) {
if (!!this.metadataCallback_)
this.metadataCallback_(mojoMetadataToJS(metadata));
}
setMetadataCallback(callback) {
this.metadataCallback_ = callback;
}
}
return new MediaSessionServiceMock(mojo.frameInterfaces);
});
function assert_image_equals(expected, observed) {
assert_equals(expected.src, observed.src);
assert_equals(expected.type, observed.type);
assert_equals(expected.sizes, observed.sizes);
}
function assert_metadata_equals(expected, observed) {
assert_equals(expected.title, observed.title);
assert_equals(expected.artist, observed.artist);
assert_equals(expected.album, observed.album);
assert_equals(expected.artwork.length, observed.artwork.length);
for (var i = 0; i < expected.artwork.length; i++) {
assert_image_equals(expected.artwork[i], observed.artwork[i]);
}
}
<!DOCTYPE html>
<title>MediaSession Mojo Test</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/mojo-helpers.js"></script>
<script src="resources/mediasessionservice-mock.js"></script>
<script src="resources/utils.js"></script>
<script>
async_test(function(t) {
mediaSessionServiceMock.then(m => {
m.setMetadataCallback(t.step_func(function(receivedMetadata) {
assert_equals(receivedMetadata, null);
t.done();
}));
window.navigator.mediaSession.metadata = null;
});
}, "test that null MediaMetadata is correctly propagated");
</script>
<!DOCTYPE html>
<title>Navigator MediaSession Test</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
test(function() {
assert_true(window.navigator.mediaSession instanceof MediaSession);
});
</script>
# This suite runs the tests in media/mediasession with
# --enable-blink-features=MediaSession
# For details on MediaSession implementation plan, see: http://crbug.com/497735 .
CONSOLE WARNING: line 6: dummy log entry to avoid an empty -expected.txt in virtual/
This is a testharness.js-based test.
PASS Test that MediaImage is constructed using a dictionary
PASS Test the different values allowed in MediaImage init dictionary
PASS Test the default values for MediaImage
PASS Test that passing unknown values to the dictionary is a no-op
Harness: the test ran to completion.
CONSOLE WARNING: line 9: dummy log entry to avoid an empty -expected.txt in virtual/
This is a testharness.js-based test.
PASS MediaSession() constructor
Harness: the test ran to completion.
CONSOLE WARNING: line 6: dummy log entry to avoid an empty -expected.txt in virtual/
This is a testharness.js-based test.
PASS Test that MediaMetadata is constructed using a dictionary
PASS Test the different values allowed in MediaMetadata init dictionary
PASS Test the default values for MediaMetadata
PASS Test that passing unknown values to the dictionary is a no-op
Harness: the test ran to completion.
...@@ -3756,6 +3756,12 @@ interface MediaError ...@@ -3756,6 +3756,12 @@ interface MediaError
attribute MEDIA_ERR_SRC_NOT_SUPPORTED attribute MEDIA_ERR_SRC_NOT_SUPPORTED
getter code getter code
method constructor method constructor
interface MediaImage
attribute @@toStringTag
getter sizes
getter src
getter type
method constructor
interface MediaKeyMessageEvent : Event interface MediaKeyMessageEvent : Event
attribute @@toStringTag attribute @@toStringTag
getter message getter message
...@@ -3809,6 +3815,13 @@ interface MediaList ...@@ -3809,6 +3815,13 @@ interface MediaList
method deleteMedium method deleteMedium
method item method item
setter mediaText setter mediaText
interface MediaMetadata
attribute @@toStringTag
getter album
getter artist
getter artwork
getter title
method constructor
interface MediaQueryList : EventTarget interface MediaQueryList : EventTarget
attribute @@toStringTag attribute @@toStringTag
getter matches getter matches
...@@ -3851,6 +3864,11 @@ interface MediaRecorder : EventTarget ...@@ -3851,6 +3864,11 @@ interface MediaRecorder : EventTarget
setter onresume setter onresume
setter onstart setter onstart
setter onstop setter onstop
interface MediaSession
attribute @@toStringTag
getter metadata
method constructor
setter metadata
interface MediaSettingsRange interface MediaSettingsRange
attribute @@toStringTag attribute @@toStringTag
getter current getter current
...@@ -4075,6 +4093,7 @@ interface Navigator ...@@ -4075,6 +4093,7 @@ interface Navigator
getter languages getter languages
getter maxTouchPoints getter maxTouchPoints
getter mediaDevices getter mediaDevices
getter mediaSession
getter mimeTypes getter mimeTypes
getter nfc getter nfc
getter onLine getter onLine
......
...@@ -14,5 +14,7 @@ blink_modules_sources("mediasession") { ...@@ -14,5 +14,7 @@ blink_modules_sources("mediasession") {
"MediaMetadataSanitizer.h", "MediaMetadataSanitizer.h",
"MediaSession.cpp", "MediaSession.cpp",
"MediaSession.h", "MediaSession.h",
"NavigatorMediaSession.cpp",
"NavigatorMediaSession.h",
] ]
} }
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
// https://wicg.github.io/mediasession/#the-mediasession-interface // https://wicg.github.io/mediasession/#the-mediasession-interface
[ [
Constructor(),
RuntimeEnabled=MediaSession, RuntimeEnabled=MediaSession,
] interface MediaSession { ] interface MediaSession {
[CallWith=ScriptState] attribute MediaMetadata? metadata; [CallWith=ScriptState] attribute MediaMetadata? metadata;
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "modules/mediasession/NavigatorMediaSession.h"
#include "bindings/core/v8/ExceptionStatePlaceholder.h"
#include "modules/mediasession/MediaSession.h"
#include "platform/Supplementable.h"
namespace blink {
NavigatorMediaSession::NavigatorMediaSession(Navigator&) {}
DEFINE_TRACE(NavigatorMediaSession) {
visitor->trace(m_session);
Supplement<Navigator>::trace(visitor);
}
const char* NavigatorMediaSession::supplementName() {
return "NavigatorMediaSession";
}
NavigatorMediaSession& NavigatorMediaSession::from(Navigator& navigator) {
NavigatorMediaSession* supplement = static_cast<NavigatorMediaSession*>(
Supplement<Navigator>::from(navigator, supplementName()));
if (!supplement) {
supplement = new NavigatorMediaSession(navigator);
provideTo(navigator, supplementName(), supplement);
}
return *supplement;
}
MediaSession* NavigatorMediaSession::mediaSession(Navigator& navigator) {
NavigatorMediaSession& self = NavigatorMediaSession::from(navigator);
if (!self.m_session)
self.m_session = MediaSession::create();
return self.m_session.get();
}
} // namespace blink
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NavigatorMediaSession_h
#define NavigatorMediaSession_h
#include "core/frame/Navigator.h"
#include "modules/mediasession/MediaSession.h"
#include "platform/Supplementable.h"
namespace blink {
class Navigator;
// Provides MediaSession as a supplement of Navigator as an attribute.
class NavigatorMediaSession final
: public GarbageCollected<NavigatorMediaSession>,
public Supplement<Navigator> {
USING_GARBAGE_COLLECTED_MIXIN(NavigatorMediaSession);
public:
static NavigatorMediaSession& from(Navigator&);
static MediaSession* mediaSession(Navigator&);
DECLARE_TRACE();
private:
NavigatorMediaSession(Navigator&);
static const char* supplementName();
// The MediaSession instance of this Navigator.
Member<MediaSession> m_session;
};
} // namespace blink
#endif // NavigatorMediaSession_h
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// https://wicg.github.io/mediasession/#the-mediasession-interface
[
Exposed=(Window),
RuntimeEnabled=MediaSession
] partial interface Navigator {
readonly attribute MediaSession mediaSession;
};
...@@ -549,6 +549,7 @@ modules_dependency_idl_files = ...@@ -549,6 +549,7 @@ modules_dependency_idl_files =
"installedapp/NavigatorInstalledApp.idl", "installedapp/NavigatorInstalledApp.idl",
"mediacapturefromelement/HTMLCanvasElementCapture.idl", "mediacapturefromelement/HTMLCanvasElementCapture.idl",
"mediacapturefromelement/HTMLMediaElementCapture.idl", "mediacapturefromelement/HTMLMediaElementCapture.idl",
"mediasession/NavigatorMediaSession.idl",
"mediasource/AudioTrackSourceBuffer.idl", "mediasource/AudioTrackSourceBuffer.idl",
"mediasource/VideoTrackSourceBuffer.idl", "mediasource/VideoTrackSourceBuffer.idl",
"mediasource/HTMLVideoElementMediaSource.idl", "mediasource/HTMLVideoElementMediaSource.idl",
......
...@@ -128,7 +128,7 @@ MediaCaptureFromVideo status=experimental ...@@ -128,7 +128,7 @@ MediaCaptureFromVideo status=experimental
MediaConstraints status=stable MediaConstraints status=stable
MediaDocumentDownloadButton MediaDocumentDownloadButton
MediaGetSettings status=test MediaGetSettings status=test
MediaSession MediaSession status=test
MediaSourceExperimental status=experimental MediaSourceExperimental status=experimental
MediaSourceNewAbortAndDuration status=experimental MediaSourceNewAbortAndDuration status=experimental
MediaStreamSpeech status=experimental MediaStreamSpeech status=experimental
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment