Bug 1046245 - enumerateDevices (harmless interface version). r=smaug, r=jesup
☠☠ backed out by 99c3baae746d ☠ ☠
authorJan-Ivar Bruaroey <jib@mozilla.com>
Tue, 03 Mar 2015 09:51:05 -0500
changeset 265259 d1ac67faccbbaa92c68f8d9f2a5b702f32fa4c23
parent 265258 142d9ae5826c9bddf3ce111895c6a4ff883b30c8
child 265260 2b99b193828ac8f8f66adb2803bc1b3448ede6ce
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, jesup
bugs1046245
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1046245 - enumerateDevices (harmless interface version). r=smaug, r=jesup
dom/media/MediaDeviceInfo.cpp
dom/media/MediaDeviceInfo.h
dom/media/MediaDevices.cpp
dom/media/MediaDevices.h
dom/media/MediaManager.cpp
dom/media/MediaManager.h
dom/media/moz.build
dom/tests/mochitest/general/test_interfaces.html
dom/webidl/MediaDeviceInfo.webidl
dom/webidl/MediaDevices.webidl
dom/webidl/moz.build
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaDeviceInfo.cpp
@@ -0,0 +1,67 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/MediaDeviceInfo.h"
+#include "mozilla/dom/MediaStreamBinding.h"
+#include "mozilla/MediaManager.h"
+#include "nsIScriptGlobalObject.h"
+
+namespace mozilla {
+namespace dom {
+
+MediaDeviceInfo::MediaDeviceInfo(const nsAString& aDeviceId,
+                                 MediaDeviceKind aKind,
+                                 const nsAString& aLabel,
+                                 const nsAString& aGroupId)
+  : mKind(aKind)
+  , mDeviceId(aDeviceId)
+  , mLabel(aLabel)
+  , mGroupId(aGroupId) {}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MediaDeviceInfo)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaDeviceInfo)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaDeviceInfo)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaDeviceInfo)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+JSObject*
+MediaDeviceInfo::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return MediaDeviceInfoBinding::Wrap(aCx, this, aGivenProto);
+}
+
+nsISupports* MediaDeviceInfo::GetParentObject()
+{
+  return nullptr;
+}
+
+void MediaDeviceInfo::GetDeviceId(nsString& retval)
+{
+  retval = mDeviceId;
+}
+
+MediaDeviceKind
+MediaDeviceInfo::Kind()
+{
+  return mKind;
+}
+
+void MediaDeviceInfo::GetGroupId(nsString& retval)
+{
+  retval = mGroupId;
+}
+
+void MediaDeviceInfo::GetLabel(nsString& retval)
+{
+  retval = mLabel;
+}
+
+MediaDeviceKind Kind();
+void GetLabel(nsString& retval);
+void GetGroupId(nsString& retval);
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaDeviceInfo.h
@@ -0,0 +1,60 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_MediaDeviceInfo_h
+#define mozilla_dom_MediaDeviceInfo_h
+
+#include "mozilla/ErrorResult.h"
+#include "nsISupportsImpl.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "MediaDeviceInfoBinding.h"
+#include "nsPIDOMWindow.h"
+
+namespace mozilla {
+namespace dom {
+
+class Promise;
+struct MediaStreamConstraints;
+
+#define MOZILLA_DOM_MEDIADEVICEINFO_IMPLEMENTATION_IID \
+{0x25091870, 0x84d6, 0x4acf, {0xaf, 0x97, 0x6e, 0xd5, 0x5b, 0xe0, 0x47, 0xb2}}
+
+class MediaDeviceInfo final : public nsISupports, public nsWrapperCache
+{
+public:
+  explicit MediaDeviceInfo(const nsAString& aDeviceId,
+                           MediaDeviceKind aKind,
+                           const nsAString& aLabel,
+                           const nsAString& aGroupId = nsString());
+
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaDeviceInfo)
+  NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIADEVICEINFO_IMPLEMENTATION_IID)
+
+  JSObject*
+  WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
+
+  nsISupports* GetParentObject();
+
+  void GetDeviceId(nsString& retval);
+  MediaDeviceKind Kind();
+  void GetLabel(nsString& retval);
+  void GetGroupId(nsString& retval);
+
+private:
+  MediaDeviceKind mKind;
+  nsString mDeviceId;
+  nsString mLabel;
+  nsString mGroupId;
+
+  virtual ~MediaDeviceInfo() {}
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(MediaDeviceInfo,
+                              MOZILLA_DOM_MEDIADEVICEINFO_IMPLEMENTATION_IID)
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_MediaDeviceInfo_h
--- a/dom/media/MediaDevices.cpp
+++ b/dom/media/MediaDevices.cpp
@@ -32,16 +32,77 @@ public:
     return NS_OK;
   }
 
 private:
   virtual ~GumResolver() {}
   nsRefPtr<Promise> mPromise;
 };
 
+class MediaDevices::EnumDevResolver : public nsIGetUserMediaDevicesSuccessCallback
+{
+public:
+  NS_DECL_ISUPPORTS
+
+  explicit EnumDevResolver(Promise* aPromise) : mPromise(aPromise) {}
+
+  NS_IMETHOD
+  OnSuccess(nsIVariant* aDevices) override
+  {
+    // Cribbed from MediaPermissionGonk.cpp
+    nsIID elementIID;
+    uint16_t elementType;
+
+    // Create array for nsIMediaDevice
+    nsTArray<nsCOMPtr<nsIMediaDevice>> devices;
+    // Contain the fumes
+    {
+      void* rawArray;
+      uint32_t arrayLen;
+      nsresult rv;
+      rv = aDevices->GetAsArray(&elementType, &elementIID, &arrayLen, &rawArray);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      if (elementType != nsIDataType::VTYPE_INTERFACE) {
+        NS_Free(rawArray);
+        return NS_ERROR_FAILURE;
+      }
+
+      nsISupports **supportsArray = reinterpret_cast<nsISupports **>(rawArray);
+      for (uint32_t i = 0; i < arrayLen; ++i) {
+        nsCOMPtr<nsIMediaDevice> device(do_QueryInterface(supportsArray[i]));
+        devices.AppendElement(device);
+        NS_IF_RELEASE(supportsArray[i]); // explicitly decrease refcount for rawptr
+      }
+      NS_Free(rawArray); // explicitly free memory from nsIVariant::GetAsArray
+    }
+    nsTArray<nsRefPtr<MediaDeviceInfo>> infos;
+    for (auto& device : devices) {
+      nsString type;
+      device->GetType(type);
+      bool isVideo = type.EqualsLiteral("video");
+      bool isAudio = type.EqualsLiteral("audio");
+      if (isVideo || isAudio) {
+        MediaDeviceKind kind = isVideo ?
+            MediaDeviceKind::Videoinput : MediaDeviceKind::Audioinput;
+        // TODO: return anonymized id, +label (origins w/gUM permission) (1046245)
+        nsRefPtr<MediaDeviceInfo> info = new MediaDeviceInfo(nsString(), kind,
+                                                             nsString());
+        infos.AppendElement(info);
+      }
+    }
+    mPromise->MaybeResolve(infos);
+    return NS_OK;
+  }
+
+private:
+  virtual ~EnumDevResolver() {}
+  nsRefPtr<Promise> mPromise;
+};
+
 class MediaDevices::GumRejecter : public nsIDOMGetUserMediaErrorCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   explicit GumRejecter(Promise* aPromise) : mPromise(aPromise) {}
 
   NS_IMETHOD
@@ -56,36 +117,51 @@ public:
   }
 
 private:
   virtual ~GumRejecter() {}
   nsRefPtr<Promise> mPromise;
 };
 
 NS_IMPL_ISUPPORTS(MediaDevices::GumResolver, nsIDOMGetUserMediaSuccessCallback)
+NS_IMPL_ISUPPORTS(MediaDevices::EnumDevResolver, nsIGetUserMediaDevicesSuccessCallback)
 NS_IMPL_ISUPPORTS(MediaDevices::GumRejecter, nsIDOMGetUserMediaErrorCallback)
 
 already_AddRefed<Promise>
 MediaDevices::GetUserMedia(const MediaStreamConstraints& aConstraints,
                            ErrorResult &aRv)
 {
-  ErrorResult rv;
   nsPIDOMWindow* window = GetOwner();
   nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(window);
   nsRefPtr<Promise> p = Promise::Create(go, aRv);
-  NS_ENSURE_TRUE(!rv.Failed(), nullptr);
+  NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
 
   nsRefPtr<GumResolver> resolver = new GumResolver(p);
   nsRefPtr<GumRejecter> rejecter = new GumRejecter(p);
 
   aRv = MediaManager::Get()->GetUserMedia(window, aConstraints,
                                           resolver, rejecter);
   return p.forget();
 }
 
+already_AddRefed<Promise>
+MediaDevices::EnumerateDevices(ErrorResult &aRv)
+{
+  nsPIDOMWindow* window = GetOwner();
+  nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(window);
+  nsRefPtr<Promise> p = Promise::Create(go, aRv);
+  NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
+
+  nsRefPtr<EnumDevResolver> resolver = new EnumDevResolver(p);
+  nsRefPtr<GumRejecter> rejecter = new GumRejecter(p);
+
+  aRv = MediaManager::Get()->EnumerateDevices(window, resolver, rejecter);
+  return p.forget();
+}
+
 NS_IMPL_ADDREF_INHERITED(MediaDevices, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(MediaDevices, DOMEventTargetHelper)
 NS_INTERFACE_MAP_BEGIN(MediaDevices)
   NS_INTERFACE_MAP_ENTRY(MediaDevices)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 JSObject*
 MediaDevices::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
--- a/dom/media/MediaDevices.h
+++ b/dom/media/MediaDevices.h
@@ -1,14 +1,14 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
-#ifndef MediaDevices_h__
-#define MediaDevices_h__
+#ifndef mozilla_dom_MediaDevices_h
+#define mozilla_dom_MediaDevices_h
 
 #include "mozilla/ErrorResult.h"
 #include "nsISupportsImpl.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "nsPIDOMWindow.h"
 
 namespace mozilla {
@@ -30,22 +30,26 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
 
   JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
 
   already_AddRefed<Promise>
   GetUserMedia(const MediaStreamConstraints& aConstraints, ErrorResult &aRv);
 
+  already_AddRefed<Promise>
+  EnumerateDevices(ErrorResult &aRv);
+
 private:
   class GumResolver;
+  class EnumDevResolver;
   class GumRejecter;
 
   virtual ~MediaDevices() {}
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(MediaDevices,
                               MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
 
 } // namespace dom
 } // namespace mozilla
 
-#endif // MediaDevices_h__
+#endif // mozilla_dom_MediaDevices_h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1572,26 +1572,18 @@ MediaManager::GetUserMedia(
     // Hack: should init singleton earlier unless it's expensive (mem or CPU)
     (void) MediaManager::Get();
 #ifdef MOZ_B2G
     // Initialize MediaPermissionManager before send out any permission request.
     (void) MediaPermissionManager::GetInstance();
 #endif //MOZ_B2G
   }
 
-  // Store the WindowID in a hash table and mark as active. The entry is removed
-  // when this window is closed or navigated away from.
   uint64_t windowID = aWindow->WindowID();
-  // This is safe since we're on main-thread, and the windowlist can only
-  // be invalidated from the main-thread (see OnNavigation)
-  StreamListeners* listeners = GetActiveWindows()->Get(windowID);
-  if (!listeners) {
-    listeners = new StreamListeners;
-    GetActiveWindows()->Put(windowID, listeners);
-  }
+  StreamListeners* listeners = AddWindowID(windowID);
 
   // Create a disabled listener to act as a placeholder
   GetUserMediaCallbackMediaStreamListener* listener =
     new GetUserMediaCallbackMediaStreamListener(mMediaThread, windowID);
 
   // No need for locking because we always do this in the main thread.
   listeners->AppendElement(listener);
 
@@ -1823,16 +1815,31 @@ MediaManager::GetUserMediaDevices(nsPIDO
     new GetUserMediaDevicesTask(
       aConstraints, onSuccess.forget(), onFailure.forget(),
       (aInnerWindowID ? aInnerWindowID : aWindow->WindowID()),
       loopbackAudioDevice, loopbackVideoDevice, useFakeStreams));
 
   return NS_OK;
 }
 
+nsresult
+MediaManager::EnumerateDevices(nsPIDOMWindow* aWindow,
+                               nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
+                               nsIDOMGetUserMediaErrorCallback* aOnFailure)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
+
+  MediaStreamConstraints c;
+  c.mVideo.SetAsBoolean() = true;
+  c.mAudio.SetAsBoolean() = true;
+
+  AddWindowID(aWindow->WindowID());
+  return GetUserMediaDevices(aWindow, c, aOnSuccess, aOnFailure, 0);
+}
+
 MediaEngine*
 MediaManager::GetBackend(uint64_t aWindowId)
 {
   // Plugin backends as appropriate. The default engine also currently
   // includes picture support for Android.
   // This IS called off main-thread.
   MutexAutoLock lock(mMutex);
   if (!mBackend) {
@@ -1891,16 +1898,32 @@ MediaManager::OnNavigation(uint64_t aWin
       (nsGlobalWindow::GetInnerWindowWithId(aWindowID));
   if (window) {
     IterateWindowListeners(window, StopSharingCallback, nullptr);
   } else {
     RemoveWindowID(aWindowID);
   }
 }
 
+StreamListeners*
+MediaManager::AddWindowID(uint64_t aWindowId)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
+  // Store the WindowID in a hash table and mark as active. The entry is removed
+  // when this window is closed or navigated away from.
+  // This is safe since we're on main-thread, and the windowlist can only
+  // be invalidated from the main-thread (see OnNavigation)
+  StreamListeners* listeners = GetActiveWindows()->Get(aWindowId);
+  if (!listeners) {
+    listeners = new StreamListeners;
+    GetActiveWindows()->Put(aWindowId, listeners);
+  }
+  return listeners;
+}
+
 void
 MediaManager::RemoveWindowID(uint64_t aWindowId)
 {
   mActiveWindows.Remove(aWindowId);
 
   // get outer windowID
   nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
     (nsGlobalWindow::GetInnerWindowWithId(aWindowId));
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -591,21 +591,28 @@ public:
     nsIDOMGetUserMediaSuccessCallback* onSuccess,
     nsIDOMGetUserMediaErrorCallback* onError);
 
   nsresult GetUserMediaDevices(nsPIDOMWindow* aWindow,
     const dom::MediaStreamConstraints& aConstraints,
     nsIGetUserMediaDevicesSuccessCallback* onSuccess,
     nsIDOMGetUserMediaErrorCallback* onError,
     uint64_t aInnerWindowID = 0);
+
+  nsresult EnumerateDevices(nsPIDOMWindow* aWindow,
+                            nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
+                            nsIDOMGetUserMediaErrorCallback* aOnFailure);
+
+  nsresult EnumerateDevices(nsPIDOMWindow* aWindow, dom::Promise& aPromise);
   void OnNavigation(uint64_t aWindowID);
 
   MediaEnginePrefs mPrefs;
 
 private:
+  StreamListeners* AddWindowID(uint64_t aWindowId);
   WindowTable *GetActiveWindows() {
     NS_ASSERTION(NS_IsMainThread(), "Only access windowlist on main thread");
     return &mActiveWindows;
   }
 
   void GetPref(nsIPrefBranch *aBranch, const char *aPref,
                const char *aData, int32_t *aVal);
   void GetPrefBool(nsIPrefBranch *aBranch, const char *aPref,
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -141,16 +141,17 @@ if CONFIG['MOZ_B2G']:
         'MediaPermissionGonk.h',
     ]
 
 EXPORTS.mozilla.dom += [
     'AudioStreamTrack.h',
     'AudioTrack.h',
     'AudioTrackList.h',
     'GetUserMediaRequest.h',
+    'MediaDeviceInfo.h',
     'MediaDevices.h',
     'MediaStreamError.h',
     'MediaStreamTrack.h',
     'RTCIdentityProviderRegistrar.h',
     'TextTrack.h',
     'TextTrackCue.h',
     'TextTrackCueList.h',
     'TextTrackList.h',
@@ -178,16 +179,17 @@ UNIFIED_SOURCES += [
     'GetUserMediaRequest.cpp',
     'GraphDriver.cpp',
     'Latency.cpp',
     'MediaCache.cpp',
     'MediaData.cpp',
     'MediaDecoder.cpp',
     'MediaDecoderReader.cpp',
     'MediaDecoderStateMachine.cpp',
+    'MediaDeviceInfo.cpp',
     'MediaDevices.cpp',
     'MediaManager.cpp',
     'MediaRecorder.cpp',
     'MediaResource.cpp',
     'MediaShutdownManager.cpp',
     'MediaStreamError.cpp',
     'MediaStreamGraph.cpp',
     'MediaStreamTrack.cpp',
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -640,16 +640,18 @@ var interfaceNamesInGlobalScope =
     "KeyEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "KeyboardEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "LocalMediaStream",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Location",
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    "MediaDeviceInfo",
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaDevices",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaElementAudioSourceNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaError",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MediaKeyError", pref: "media.eme.apiVisible"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MediaDeviceInfo.webidl
@@ -0,0 +1,22 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * http://dev.w3.org/2011/webrtc/editor/getusermedia.html
+ */
+
+enum MediaDeviceKind {
+  "audioinput",
+  "audiooutput",
+  "videoinput"
+};
+
+[Func="Navigator::HasUserMediaSupport"]
+interface MediaDeviceInfo {
+  readonly attribute DOMString       deviceId;
+  readonly attribute MediaDeviceKind kind;
+  readonly attribute DOMString       label;
+  readonly attribute DOMString       groupId;
+};
--- a/dom/webidl/MediaDevices.webidl
+++ b/dom/webidl/MediaDevices.webidl
@@ -7,17 +7,17 @@
  * http://dev.w3.org/2011/webrtc/editor/getusermedia.html
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Func="Navigator::HasUserMediaSupport"]
 interface MediaDevices : EventTarget {
-//    attribute EventHandler ondevicechange;
-//
-//    void enumerateDevices (MediaDeviceInfoCallback resultCallback);
-//
+//  attribute EventHandler ondevicechange;
 //  static Dictionary getSupportedConstraints (DOMString kind);
 
-  [Throws, Func="Navigator::HasUserMediaSupport"]
+  [Throws]
+  Promise<sequence<MediaDeviceInfo>> enumerateDevices();
+
+  [Throws]
   Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
 };
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -257,16 +257,17 @@ WEBIDL_FILES = [
     'KeyAlgorithm.webidl',
     'KeyboardEvent.webidl',
     'KeyEvent.webidl',
     'LegacyQueryInterface.webidl',
     'LinkStyle.webidl',
     'ListBoxObject.webidl',
     'LocalMediaStream.webidl',
     'Location.webidl',
+    'MediaDeviceInfo.webidl',
     'MediaDevices.webidl',
     'MediaElementAudioSourceNode.webidl',
     'MediaError.webidl',
     'MediaList.webidl',
     'MediaQueryList.webidl',
     'MediaRecorder.webidl',
     'MediaSource.webidl',
     'MediaStream.webidl',