Bug 1046245 - enumerateDevices (harmless interface version). r=smaug, r=jesup
☠☠ backed out by d2f789b62177 ☠ ☠
authorJan-Ivar Bruaroey <jib@mozilla.com>
Tue, 03 Mar 2015 09:51:05 -0500
changeset 236381 609f3ca64004a62e4a8d1bea24aa779104e7e46f
parent 236380 73fbc0f8d061d433fd1795a19876b7039f84c3f2
child 236382 e966a5df87b6b7c971c20b7868ed2c5939041b70
push id28497
push userphilringnalda@gmail.com
push dateSun, 29 Mar 2015 03:30:34 +0000
treeherdermozilla-central@02f2f4c75007 [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',