Bug 1279493 - Use blob URLs exclusively rather than having mediastream and mediasource URLs, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 21 Jul 2016 14:31:43 +0200
changeset 346196 d6e4999d9dd2796e243e78880a6352186493a80f
parent 346195 250943418f3a43c46de84797ad58a22f724caf58
child 346197 eb74a01c8dc0bc508ea8b492e6a4c179e1c2ff19
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1279493
milestone50.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 1279493 - Use blob URLs exclusively rather than having mediastream and mediasource URLs, r=smaug
dom/base/nsHostObjectProtocolHandler.cpp
dom/base/nsHostObjectProtocolHandler.h
dom/html/HTMLMediaElement.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/url/URL.cpp
testing/web-platform/meta/media-source/URL-createObjectURL.html.ini
--- a/dom/base/nsHostObjectProtocolHandler.cpp
+++ b/dom/base/nsHostObjectProtocolHandler.cpp
@@ -20,26 +20,56 @@
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsHostObjectURI.h"
 #include "nsIMemoryReporter.h"
 #include "nsIPrincipal.h"
 #include "nsIUUIDGenerator.h"
 #include "nsNetUtil.h"
 
+using mozilla::DOMMediaStream;
 using mozilla::dom::BlobImpl;
+using mozilla::dom::MediaSource;
 using mozilla::ErrorResult;
 using mozilla::net::LoadInfo;
 
 // -----------------------------------------------------------------------
 // Hash table
 struct DataInfo
 {
-  // mObject is expected to be an BlobImpl, DOMMediaStream, or MediaSource
-  nsCOMPtr<nsISupports> mObject;
+  enum ObjectType {
+    eBlobImpl,
+    eMediaStream,
+    eMediaSource
+  };
+
+  DataInfo(BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal)
+    : mObjectType(eBlobImpl)
+    , mBlobImpl(aBlobImpl)
+    , mPrincipal(aPrincipal)
+  {}
+
+  DataInfo(DOMMediaStream* aMediaStream, nsIPrincipal* aPrincipal)
+    : mObjectType(eMediaStream)
+    , mMediaStream(aMediaStream)
+    , mPrincipal(aPrincipal)
+  {}
+
+  DataInfo(MediaSource* aMediaSource, nsIPrincipal* aPrincipal)
+    : mObjectType(eMediaSource)
+    , mMediaSource(aMediaSource)
+    , mPrincipal(aPrincipal)
+  {}
+
+  ObjectType mObjectType;
+
+  RefPtr<BlobImpl> mBlobImpl;
+  RefPtr<DOMMediaStream> mMediaStream;
+  RefPtr<MediaSource> mMediaSource;
+
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCString mStack;
 };
 
 static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
 
 static DataInfo*
 GetDataInfo(const nsACString& aUri)
@@ -66,16 +96,31 @@ GetDataInfo(const nsACString& aUri)
   if (pos < 0) {
     gDataTable->Get(aUri, &res);
   } else {
     gDataTable->Get(StringHead(aUri, pos), &res);
   }
 
   return res;
 }
+static DataInfo*
+GetDataInfoFromURI(nsIURI* aURI)
+{
+  if (!aURI) {
+    return nullptr;
+  }
+
+  nsCString spec;
+  nsresult rv = aURI->GetSpec(spec);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return nullptr;
+  }
+
+  return GetDataInfo(spec);
+}
 
 // Memory reporting for the hash table.
 namespace mozilla {
 
 void
 BroadcastBlobURLRegistration(const nsACString& aURI,
                              BlobImpl* aBlobImpl,
                              nsIPrincipal* aPrincipal)
@@ -145,28 +190,34 @@ class BlobURLsReporter final : public ns
     if (!gDataTable) {
       return NS_OK;
     }
 
     nsDataHashtable<nsPtrHashKey<BlobImpl>, uint32_t> refCounts;
 
     // Determine number of URLs per BlobImpl, to handle the case where it's > 1.
     for (auto iter = gDataTable->Iter(); !iter.Done(); iter.Next()) {
-      nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(iter.UserData()->mObject);
-      if (blobImpl) {
-        refCounts.Put(blobImpl, refCounts.Get(blobImpl) + 1);
+      if (iter.UserData()->mObjectType != DataInfo::eBlobImpl) {
+        continue;
       }
+
+      BlobImpl* blobImpl = iter.UserData()->mBlobImpl;
+      MOZ_ASSERT(blobImpl);
+
+      refCounts.Put(blobImpl, refCounts.Get(blobImpl) + 1);
     }
 
     for (auto iter = gDataTable->Iter(); !iter.Done(); iter.Next()) {
       nsCStringHashKey::KeyType key = iter.Key();
       DataInfo* info = iter.UserData();
 
-      nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(iter.UserData()->mObject);
-      if (blobImpl) {
+      if (iter.UserData()->mObjectType == DataInfo::eBlobImpl) {
+        BlobImpl* blobImpl = iter.UserData()->mBlobImpl;
+        MOZ_ASSERT(blobImpl);
+
         NS_NAMED_LITERAL_CSTRING(desc,
           "A blob URL allocated with URL.createObjectURL; the referenced "
           "blob cannot be freed until all URLs for it have been explicitly "
           "invalidated with URL.revokeObjectURL.");
         nsAutoCString path, url, owner, specialDesc;
         nsCOMPtr<nsIURI> principalURI;
         uint64_t size = 0;
         uint32_t refCount = 1;
@@ -229,37 +280,32 @@ class BlobURLsReporter final : public ns
           aCallback->Callback(EmptyCString(),
               path,
               KIND_OTHER,
               UNITS_COUNT,
               1,
               descString,
               aData);
         }
-      } else {
-        // Just report the path for the DOMMediaStream or MediaSource.
-        nsCOMPtr<mozilla::dom::MediaSource>
-          ms(do_QueryInterface(info->mObject));
-        nsAutoCString path;
-        path = ms ? "media-source-urls/" : "dom-media-stream-urls/";
-        BuildPath(path, key, info, aAnonymize);
+        continue;
+      }
 
-        NS_NAMED_LITERAL_CSTRING(desc,
-          "An object URL allocated with URL.createObjectURL; the referenced "
-          "data cannot be freed until all URLs for it have been explicitly "
-          "invalidated with URL.revokeObjectURL.");
+      // Just report the path for the DOMMediaStream or MediaSource.
+      nsAutoCString path;
+      path = iter.UserData()->mObjectType == DataInfo::eMediaSource
+               ? "media-source-urls/" : "dom-media-stream-urls/";
+      BuildPath(path, key, info, aAnonymize);
 
-        aCallback->Callback(EmptyCString(),
-            path,
-            KIND_OTHER,
-            UNITS_COUNT,
-            1,
-            desc,
-            aData);
-      }
+      NS_NAMED_LITERAL_CSTRING(desc,
+        "An object URL allocated with URL.createObjectURL; the referenced "
+        "data cannot be freed until all URLs for it have been explicitly "
+        "invalidated with URL.revokeObjectURL.");
+
+      aCallback->Callback(EmptyCString(), path, KIND_OTHER, UNITS_COUNT, 1,
+                          desc, aData);
     }
 
     return NS_OK;
   }
 
   // Initialize info->mStack to record JS stack info, if enabled.
   // The string generated here is used in ReportCallback, below.
   static void GetJSStackForBlob(DataInfo* aInfo)
@@ -365,16 +411,32 @@ class BlobURLsReporter final : public ns
     }
   }
 };
 
 NS_IMPL_ISUPPORTS(BlobURLsReporter, nsIMemoryReporter)
 
 } // namespace mozilla
 
+template<typename T>
+static nsresult
+AddDataEntryInternal(const nsACString& aURI, T aObject,
+                     nsIPrincipal* aPrincipal)
+{
+  if (!gDataTable) {
+    gDataTable = new nsClassHashtable<nsCStringHashKey, DataInfo>;
+  }
+
+  DataInfo* info = new DataInfo(aObject, aPrincipal);
+  mozilla::BlobURLsReporter::GetJSStackForBlob(info);
+
+  gDataTable->Put(aURI, info);
+  return NS_OK;
+}
+
 void
 nsHostObjectProtocolHandler::Init(void)
 {
   static bool initialized = false;
 
   if (!initialized) {
     initialized = true;
     RegisterStrongMemoryReporter(new mozilla::HostObjectURLsReporter());
@@ -382,88 +444,93 @@ nsHostObjectProtocolHandler::Init(void)
   }
 }
 
 nsHostObjectProtocolHandler::nsHostObjectProtocolHandler()
 {
   Init();
 }
 
-nsresult
-nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
-                                          nsISupports* aObject,
+/* static */ nsresult
+nsHostObjectProtocolHandler::AddDataEntry(BlobImpl* aBlobImpl,
+                                          nsIPrincipal* aPrincipal,
+                                          nsACString& aUri)
+{
+  Init();
+
+  nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = AddDataEntryInternal(aUri, aBlobImpl, aPrincipal);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  BroadcastBlobURLRegistration(aUri, aBlobImpl, aPrincipal);
+  return NS_OK;
+}
+
+/* static */ nsresult
+nsHostObjectProtocolHandler::AddDataEntry(DOMMediaStream* aMediaStream,
                                           nsIPrincipal* aPrincipal,
                                           nsACString& aUri)
 {
-#ifdef DEBUG
-  {
-    nsCOMPtr<BlobImpl> blobImpl(do_QueryInterface(aObject));
-    nsCOMPtr<MediaSource> mediaSource(do_QueryInterface(aObject));
-    nsCOMPtr<DOMMediaStream> mediaStream(do_QueryInterface(aObject));
-
-    // We support only these types.
-    MOZ_ASSERT(blobImpl || mediaSource || mediaStream);
-  }
-#endif
-
   Init();
 
-  nsresult rv = GenerateURIString(aScheme, aPrincipal, aUri);
+  nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = AddDataEntryInternal(aUri, aMediaStream, aPrincipal);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = AddDataEntry(aUri, aObject, aPrincipal);
+  return NS_OK;
+}
+
+/* static */ nsresult
+nsHostObjectProtocolHandler::AddDataEntry(MediaSource* aMediaSource,
+                                          nsIPrincipal* aPrincipal,
+                                          nsACString& aUri)
+{
+  Init();
+
+  nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(aObject);
-  if (blobImpl) {
-    BroadcastBlobURLRegistration(aUri, blobImpl, aPrincipal);
-  }
+  rv = AddDataEntryInternal(aUri, aMediaSource, aPrincipal);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 /* static */ nsresult
 nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aURI,
-                                          nsISupports* aObject,
-                                          nsIPrincipal* aPrincipal)
+                                          nsIPrincipal* aPrincipal,
+                                          mozilla::dom::BlobImpl* aBlobImpl)
 {
-  if (!gDataTable) {
-    gDataTable = new nsClassHashtable<nsCStringHashKey, DataInfo>;
-  }
-
-  DataInfo* info = new DataInfo;
-
-  info->mObject = aObject;
-  info->mPrincipal = aPrincipal;
-  mozilla::BlobURLsReporter::GetJSStackForBlob(info);
-
-  gDataTable->Put(aURI, info);
-  return NS_OK;
+  return AddDataEntryInternal(aURI, aBlobImpl, aPrincipal);
 }
 
 /* static */ bool
 nsHostObjectProtocolHandler::GetAllBlobURLEntries(nsTArray<BlobURLRegistrationData>& aRegistrations,
                                                   ContentParent* aCP)
 {
   MOZ_ASSERT(aCP);
 
   if (!gDataTable) {
     return true;
   }
 
   for (auto iter = gDataTable->ConstIter(); !iter.Done(); iter.Next()) {
     DataInfo* info = iter.UserData();
     MOZ_ASSERT(info);
 
-    nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(info->mObject);
-    if (!blobImpl) {
+    if (info->mObjectType != DataInfo::eBlobImpl) {
       continue;
     }
 
-    PBlobParent* blobParent = aCP->GetOrCreateActorForBlobImpl(blobImpl);
+    MOZ_ASSERT(info->mBlobImpl);
+    PBlobParent* blobParent = aCP->GetOrCreateActorForBlobImpl(info->mBlobImpl);
     if (!blobParent) {
       return false;
     }
 
     aRegistrations.AppendElement(
       BlobURLRegistrationData(nsCString(iter.Key()), blobParent, nullptr,
                               IPC::Principal(info->mPrincipal)));
   }
@@ -479,21 +546,18 @@ nsHostObjectProtocolHandler::RemoveDataE
     return;
   }
 
   DataInfo* info = GetDataInfo(aUri);
   if (!info) {
     return;
   }
 
-  if (aBroadcastToOtherProcesses) {
-    nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(info->mObject);
-    if (blobImpl) {
-      BroadcastBlobURLUnregistration(aUri, info);
-    }
+  if (aBroadcastToOtherProcesses && info->mObjectType == DataInfo::eBlobImpl) {
+    BroadcastBlobURLUnregistration(aUri, info);
   }
 
   gDataTable->Remove(aUri);
   if (gDataTable->Count() == 0) {
     delete gDataTable;
     gDataTable = nullptr;
   }
 }
@@ -543,16 +607,24 @@ nsHostObjectProtocolHandler::GenerateURI
     aUri.Append('/');
   }
 
   aUri += Substring(chars + 1, chars + NSID_LENGTH - 2);
 
   return NS_OK;
 }
 
+nsresult
+nsHostObjectProtocolHandler::GenerateURIStringForBlobURL(nsIPrincipal* aPrincipal,
+                                                         nsACString& aUri)
+{
+  return
+    GenerateURIString(NS_LITERAL_CSTRING(BLOBURI_SCHEME), aPrincipal, aUri);
+}
+
 nsIPrincipal*
 nsHostObjectProtocolHandler::GetDataEntryPrincipal(const nsACString& aUri)
 {
   if (!gDataTable) {
     return nullptr;
   }
 
   DataInfo* res = GetDataInfo(aUri);
@@ -573,33 +645,24 @@ nsHostObjectProtocolHandler::Traverse(co
   }
 
   DataInfo* res;
   gDataTable->Get(aUri, &res);
   if (!res) {
     return;
   }
 
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mObject");
-  aCallback.NoteXPCOMChild(res->mObject);
-}
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mBlobImpl");
+  aCallback.NoteXPCOMChild(res->mBlobImpl);
 
-static nsISupports*
-GetDataObjectForSpec(const nsACString& aSpec)
-{
-  DataInfo* info = GetDataInfo(aSpec);
-  return info ? info->mObject : nullptr;
-}
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mMediaSource");
+  aCallback.NoteXPCOMChild(res->mMediaSource);
 
-static nsISupports*
-GetDataObject(nsIURI* aURI)
-{
-  nsCString spec;
-  aURI->GetSpec(spec);
-  return GetDataObjectForSpec(spec);
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mMediaStream");
+  aCallback.NoteXPCOMChild(res->mMediaStream);
 }
 
 // -----------------------------------------------------------------------
 // Protocol handler
 
 NS_IMPL_ISUPPORTS(nsHostObjectProtocolHandler, nsIProtocolHandler)
 
 NS_IMETHODIMP
@@ -624,19 +687,19 @@ nsHostObjectProtocolHandler::NewURI(cons
                                     nsIURI **aResult)
 {
   *aResult = nullptr;
   nsresult rv;
 
   DataInfo* info = GetDataInfo(aSpec);
 
   RefPtr<nsHostObjectURI> uri;
-  if (info) {
-    nsCOMPtr<BlobImpl> blob = do_QueryInterface(info->mObject);
-    uri = new nsHostObjectURI(info->mPrincipal, blob);
+  if (info && info->mObjectType == DataInfo::eBlobImpl) {
+    MOZ_ASSERT(info->mBlobImpl);
+    uri = new nsHostObjectURI(info->mPrincipal, info->mBlobImpl);
   } else {
     uri = new nsHostObjectURI(nullptr, nullptr);
   }
 
   rv = uri->SetSpec(aSpec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_TryToSetImmutable(uri);
@@ -660,20 +723,17 @@ nsHostObjectProtocolHandler::NewChannel2
   nsCOMPtr<nsISupports> tmp;
   MOZ_ALWAYS_SUCCEEDS(uriBlobImpl->GetBlobImpl(getter_AddRefs(tmp)));
   nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(tmp);
   if (!blobImpl) {
     return NS_ERROR_DOM_BAD_URI;
   }
 
 #ifdef DEBUG
-  nsCString spec;
-  uri->GetSpec(spec);
-
-  DataInfo* info = GetDataInfo(spec);
+  DataInfo* info = GetDataInfoFromURI(uri);
 
   // Info can be null, in case this blob URL has been revoked already.
   if (info) {
     nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(uri);
     nsCOMPtr<nsIPrincipal> principal;
     uriPrinc->GetPrincipal(getter_AddRefs(principal));
     NS_ASSERTION(info->mPrincipal == principal, "Wrong principal!");
   }
@@ -738,62 +798,50 @@ nsHostObjectProtocolHandler::AllowPort(i
 NS_IMETHODIMP
 nsBlobProtocolHandler::GetScheme(nsACString &result)
 {
   result.AssignLiteral(BLOBURI_SCHEME);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsMediaStreamProtocolHandler::GetScheme(nsACString &result)
-{
-  result.AssignLiteral(MEDIASTREAMURI_SCHEME);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsMediaSourceProtocolHandler::GetScheme(nsACString &result)
-{
-  result.AssignLiteral(MEDIASOURCEURI_SCHEME);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsFontTableProtocolHandler::GetScheme(nsACString &result)
 {
   result.AssignLiteral(FONTTABLEURI_SCHEME);
   return NS_OK;
 }
 
 nsresult
 NS_GetBlobForBlobURI(nsIURI* aURI, BlobImpl** aBlob)
 {
   NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs");
 
   *aBlob = nullptr;
 
-  nsCOMPtr<BlobImpl> blob = do_QueryInterface(GetDataObject(aURI));
-  if (!blob) {
+  DataInfo* info = GetDataInfoFromURI(aURI);
+  if (!info || info->mObjectType != DataInfo::eBlobImpl) {
     return NS_ERROR_DOM_BAD_URI;
   }
 
+  RefPtr<BlobImpl> blob = info->mBlobImpl;
   blob.forget(aBlob);
   return NS_OK;
 }
 
 nsresult
 NS_GetBlobForBlobURISpec(const nsACString& aSpec, BlobImpl** aBlob)
 {
   *aBlob = nullptr;
 
-  nsCOMPtr<BlobImpl> blob = do_QueryInterface(GetDataObjectForSpec(aSpec));
-  if (!blob) {
+  DataInfo* info = GetDataInfo(aSpec);
+  if (!info || info->mObjectType != DataInfo::eBlobImpl) {
     return NS_ERROR_DOM_BAD_URI;
   }
 
+  RefPtr<BlobImpl> blob = info->mBlobImpl;
   blob.forget(aBlob);
   return NS_OK;
 }
 
 nsresult
 NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
 {
   RefPtr<BlobImpl> blobImpl;
@@ -811,23 +859,24 @@ NS_GetStreamForBlobURI(nsIURI* aURI, nsI
   return NS_OK;
 }
 
 nsresult
 NS_GetStreamForMediaStreamURI(nsIURI* aURI, mozilla::DOMMediaStream** aStream)
 {
   NS_ASSERTION(IsMediaStreamURI(aURI), "Only call this with mediastream URIs");
 
-  nsISupports* dataObject = GetDataObject(aURI);
-  if (!dataObject) {
+  DataInfo* info = GetDataInfoFromURI(aURI);
+  if (!info || info->mObjectType != DataInfo::eMediaStream) {
     return NS_ERROR_DOM_BAD_URI;
   }
 
-  *aStream = nullptr;
-  return CallQueryInterface(dataObject, aStream);
+  RefPtr<DOMMediaStream> mediaStream = info->mMediaStream;
+  mediaStream.forget(aStream);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFontTableProtocolHandler::NewURI(const nsACString& aSpec,
                                    const char *aCharset,
                                    nsIURI *aBaseURI,
                                    nsIURI **aResult)
 {
@@ -860,67 +909,76 @@ nsFontTableProtocolHandler::NewURI(const
 
 nsresult
 NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource)
 {
   NS_ASSERTION(IsMediaSourceURI(aURI), "Only call this with mediasource URIs");
 
   *aSource = nullptr;
 
-  nsCOMPtr<mozilla::dom::MediaSource> source = do_QueryInterface(GetDataObject(aURI));
-  if (!source) {
+  DataInfo* info = GetDataInfoFromURI(aURI);
+  if (!info || info->mObjectType != DataInfo::eMediaSource) {
     return NS_ERROR_DOM_BAD_URI;
   }
 
-  source.forget(aSource);
+  RefPtr<MediaSource> mediaSource = info->mMediaSource;
+  mediaSource.forget(aSource);
   return NS_OK;
 }
 
 #define NS_BLOBPROTOCOLHANDLER_CID \
 { 0xb43964aa, 0xa078, 0x44b2, \
   { 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
 
-#define NS_MEDIASTREAMPROTOCOLHANDLER_CID \
-{ 0x27d1fa24, 0x2b73, 0x4db3, \
-  { 0xab, 0x48, 0xb9, 0x83, 0x83, 0x40, 0xe0, 0x81 } }
-
-#define NS_MEDIASOURCEPROTOCOLHANDLER_CID \
-{ 0x12ef31fc, 0xa8fb, 0x4661, \
-  { 0x9a, 0x63, 0xfb, 0x61, 0x04,0x5d, 0xb8, 0x61 } }
-
 #define NS_FONTTABLEPROTOCOLHANDLER_CID \
 { 0x3fc8f04e, 0xd719, 0x43ca, \
   { 0x9a, 0xd0, 0x18, 0xee, 0x32, 0x02, 0x11, 0xf2 } }
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaStreamProtocolHandler)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaSourceProtocolHandler)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontTableProtocolHandler)
 
 NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_CID);
-NS_DEFINE_NAMED_CID(NS_MEDIASTREAMPROTOCOLHANDLER_CID);
-NS_DEFINE_NAMED_CID(NS_MEDIASOURCEPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_FONTTABLEPROTOCOLHANDLER_CID);
 
 static const mozilla::Module::CIDEntry kHostObjectProtocolHandlerCIDs[] = {
   { &kNS_BLOBPROTOCOLHANDLER_CID, false, nullptr, nsBlobProtocolHandlerConstructor },
-  { &kNS_MEDIASTREAMPROTOCOLHANDLER_CID, false, nullptr, nsMediaStreamProtocolHandlerConstructor },
-  { &kNS_MEDIASOURCEPROTOCOLHANDLER_CID, false, nullptr, nsMediaSourceProtocolHandlerConstructor },
   { &kNS_FONTTABLEPROTOCOLHANDLER_CID, false, nullptr, nsFontTableProtocolHandlerConstructor },
   { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kHostObjectProtocolHandlerContracts[] = {
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_CID },
-  { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASTREAMURI_SCHEME, &kNS_MEDIASTREAMPROTOCOLHANDLER_CID },
-  { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASOURCEURI_SCHEME, &kNS_MEDIASOURCEPROTOCOLHANDLER_CID },
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX FONTTABLEURI_SCHEME, &kNS_FONTTABLEPROTOCOLHANDLER_CID },
   { nullptr }
 };
 
 static const mozilla::Module kHostObjectProtocolHandlerModule = {
   mozilla::Module::kVersion,
   kHostObjectProtocolHandlerCIDs,
   kHostObjectProtocolHandlerContracts
 };
 
 NSMODULE_DEFN(HostObjectProtocolHandler) = &kHostObjectProtocolHandlerModule;
 
+bool IsType(nsIURI* aUri, DataInfo::ObjectType aType)
+{
+  DataInfo* info = GetDataInfoFromURI(aUri);
+  if (!info) {
+    return false;
+  }
+
+  return info->mObjectType == aType;
+}
+
+bool IsBlobURI(nsIURI* aUri)
+{
+  return IsType(aUri, DataInfo::eBlobImpl);
+}
+
+bool IsMediaStreamURI(nsIURI* aUri)
+{
+  return IsType(aUri, DataInfo::eMediaStream);
+}
+
+bool IsMediaSourceURI(nsIURI* aUri)
+{
+  return IsType(aUri, DataInfo::eMediaSource);
+}
--- a/dom/base/nsHostObjectProtocolHandler.h
+++ b/dom/base/nsHostObjectProtocolHandler.h
@@ -10,24 +10,23 @@
 #include "mozilla/Attributes.h"
 #include "nsIProtocolHandler.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 #include "nsIInputStream.h"
 #include "nsTArray.h"
 
 #define BLOBURI_SCHEME "blob"
-#define MEDIASTREAMURI_SCHEME "mediastream"
-#define MEDIASOURCEURI_SCHEME "mediasource"
 #define FONTTABLEURI_SCHEME "moz-fonttable"
 #define RTSPURI_SCHEME "rtsp"
 
 class nsIPrincipal;
 
 namespace mozilla {
+class BlobURLsReporter;
 class DOMMediaStream;
 namespace dom {
 class BlobImpl;
 class BlobURLRegistrationData;
 class ContentParent;
 class MediaSource;
 } // namespace dom
 } // namespace mozilla
@@ -46,36 +45,44 @@ public:
   NS_IMETHOD NewChannel2(nsIURI *aURI, nsILoadInfo *aLoadinfo, nsIChannel * *_retval) override;
   NS_IMETHOD NewChannel(nsIURI *aURI, nsIChannel * *_retval) override;
   NS_IMETHOD AllowPort(int32_t port, const char * scheme, bool *_retval) override;
 
   // If principal is not null, its origin will be used to generate the URI.
   static nsresult GenerateURIString(const nsACString &aScheme,
                                     nsIPrincipal* aPrincipal,
                                     nsACString &aUri);
+  static nsresult GenerateURIStringForBlobURL(nsIPrincipal* aPrincipal,
+                                              nsACString &aUri);
 
   // Methods for managing uri->object mapping
   // AddDataEntry creates the URI with the given scheme and returns it in aUri
-  static nsresult AddDataEntry(const nsACString& aScheme,
-                               nsISupports* aObject,
+  static nsresult AddDataEntry(mozilla::dom::BlobImpl* aBlobImpl,
+                               nsIPrincipal* aPrincipal,
+                               nsACString& aUri);
+  static nsresult AddDataEntry(mozilla::DOMMediaStream* aMediaStream,
                                nsIPrincipal* aPrincipal,
                                nsACString& aUri);
+  static nsresult AddDataEntry(mozilla::dom::MediaSource* aMediaSource,
+                               nsIPrincipal* aPrincipal,
+                               nsACString& aUri);
+  // IPC only
+  static nsresult AddDataEntry(const nsACString& aURI,
+                               nsIPrincipal* aPrincipal,
+                               mozilla::dom::BlobImpl* aBlobImpl);
+
   static void RemoveDataEntry(const nsACString& aUri,
                               bool aBroadcastToOTherProcesses = true);
 
   // This is for IPC only.
   static void RemoveDataEntries();
 
   static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri);
   static void Traverse(const nsACString& aUri, nsCycleCollectionTraversalCallback& aCallback);
 
-  // IPC or internal use only
-  static nsresult AddDataEntry(const nsACString& aURI,
-                               nsISupports* aObject,
-                               nsIPrincipal* aPrincipal);
   static bool
   GetAllBlobURLEntries(nsTArray<mozilla::dom::BlobURLRegistrationData>& aRegistrations,
                        mozilla::dom::ContentParent* aCP);
 
 protected:
   virtual ~nsHostObjectProtocolHandler() {}
 
 private:
@@ -83,59 +90,39 @@ private:
 };
 
 class nsBlobProtocolHandler : public nsHostObjectProtocolHandler
 {
 public:
   NS_IMETHOD GetScheme(nsACString &result) override;
 };
 
-class nsMediaStreamProtocolHandler : public nsHostObjectProtocolHandler
-{
-public:
-  NS_IMETHOD GetScheme(nsACString &result) override;
-};
-
 class nsMediaSourceProtocolHandler : public nsHostObjectProtocolHandler
 {
 public:
   NS_IMETHOD GetScheme(nsACString &result) override;
 };
 
 class nsFontTableProtocolHandler : public nsHostObjectProtocolHandler
 {
 public:
   NS_IMETHOD GetScheme(nsACString &result);
   NS_IMETHOD NewURI(const nsACString & aSpec, const char * aOriginCharset, nsIURI *aBaseURI, nsIURI * *_retval);
 };
 
-inline bool IsBlobURI(nsIURI* aUri)
-{
-  bool isBlob;
-  return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob;
-}
+bool IsBlobURI(nsIURI* aUri);
+bool IsMediaStreamURI(nsIURI* aUri);
+bool IsMediaSourceURI(nsIURI* aUri);
 
 inline bool IsRtspURI(nsIURI* aUri)
 {
   bool isRtsp;
   return NS_SUCCEEDED(aUri->SchemeIs(RTSPURI_SCHEME, &isRtsp)) && isRtsp;
 }
 
-inline bool IsMediaStreamURI(nsIURI* aUri)
-{
-  bool isStream;
-  return NS_SUCCEEDED(aUri->SchemeIs(MEDIASTREAMURI_SCHEME, &isStream)) && isStream;
-}
-
-inline bool IsMediaSourceURI(nsIURI* aUri)
-{
-  bool isMediaSource;
-  return NS_SUCCEEDED(aUri->SchemeIs(MEDIASOURCEURI_SCHEME, &isMediaSource)) && isMediaSource;
-}
-
 inline bool IsFontTableURI(nsIURI* aUri)
 {
   bool isFont;
   return NS_SUCCEEDED(aUri->SchemeIs(FONTTABLEURI_SCHEME, &isFont)) && isFont;
 }
 
 extern nsresult
 NS_GetBlobForBlobURI(nsIURI* aURI, mozilla::dom::BlobImpl** aBlob);
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1495,19 +1495,25 @@ nsresult HTMLMediaElement::LoadResource(
   if (docShell && !docShell->GetAllowMedia()) {
     return NS_ERROR_FAILURE;
   }
 
   // Set the media element's CORS mode only when loading a resource
   mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 
 #ifdef MOZ_EME
+  bool isBlob = false;
   if (mMediaKeys &&
-      !IsMediaSourceURI(mLoadingSrc) &&
-      Preferences::GetBool("media.eme.mse-only", true)) {
+      Preferences::GetBool("media.eme.mse-only", true) &&
+      // We only want mediaSource URLs, but they are BlobURL, so we have to
+      // check the schema and if they are not MediaStream or real Blob.
+      (NS_FAILED(mLoadingSrc->SchemeIs(BLOBURI_SCHEME, &isBlob)) ||
+       !isBlob ||
+       IsMediaStreamURI(mLoadingSrc) ||
+       IsBlobURI(mLoadingSrc))) {
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
   }
 #endif
 
   HTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
   if (other && other->mDecoder) {
     // Clone it.
     nsresult rv = InitializeDecoderAsClone(other->mDecoder);
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2639,18 +2639,19 @@ bool
 ContentChild::RecvInitBlobURLs(nsTArray<BlobURLRegistrationData>&& aRegistrations)
 {
   for (uint32_t i = 0; i < aRegistrations.Length(); ++i) {
     BlobURLRegistrationData& registration = aRegistrations[i];
     RefPtr<BlobImpl> blobImpl =
       static_cast<BlobChild*>(registration.blobChild())->GetBlobImpl();
     MOZ_ASSERT(blobImpl);
 
-    nsHostObjectProtocolHandler::AddDataEntry(registration.url(), blobImpl,
-                                              registration.principal());
+    nsHostObjectProtocolHandler::AddDataEntry(registration.url(),
+                                              registration.principal(),
+                                              blobImpl);
   }
 
   return true;
 }
 
 bool
 ContentChild::RecvLastPrivateDocShellDestroyed()
 {
@@ -3391,17 +3392,17 @@ ContentChild::RecvNotifyPushSubscription
 
 bool
 ContentChild::RecvBlobURLRegistration(const nsCString& aURI, PBlobChild* aBlobChild,
                                       const IPC::Principal& aPrincipal)
 {
   RefPtr<BlobImpl> blobImpl = static_cast<BlobChild*>(aBlobChild)->GetBlobImpl();
   MOZ_ASSERT(blobImpl);
 
-  nsHostObjectProtocolHandler::AddDataEntry(aURI, blobImpl, aPrincipal);
+  nsHostObjectProtocolHandler::AddDataEntry(aURI, aPrincipal, blobImpl);
   return true;
 }
 
 bool
 ContentChild::RecvBlobURLUnregistration(const nsCString& aURI)
 {
   nsHostObjectProtocolHandler::RemoveDataEntry(aURI);
   return true;
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5744,18 +5744,18 @@ ContentParent::RecvStoreAndBroadcastBlob
                                                         const Principal& aPrincipal)
 {
   RefPtr<BlobImpl> blobImpl =
     static_cast<BlobParent*>(aBlobParent)->GetBlobImpl();
   if (NS_WARN_IF(!blobImpl)) {
     return false;
   }
 
-  if (NS_SUCCEEDED(nsHostObjectProtocolHandler::AddDataEntry(aURI, blobImpl,
-                                                             aPrincipal))) {
+  if (NS_SUCCEEDED(nsHostObjectProtocolHandler::AddDataEntry(aURI, aPrincipal,
+                                                             blobImpl))) {
     BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
 
     // We want to store this blobURL, so we can unregister it if the child
     // crashes.
     mBlobURLs.AppendElement(aURI);
   }
 
   BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
--- a/dom/url/URL.cpp
+++ b/dom/url/URL.cpp
@@ -29,16 +29,40 @@ namespace mozilla {
 namespace dom {
 
 ///////////////////////////////////////////////////////////////////////////////
 // URL for main-thread
 ///////////////////////////////////////////////////////////////////////////////
 
 namespace {
 
+template<typename T>
+void
+CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
+                        nsAString& aResult, ErrorResult& aRv)
+{
+  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
+  if (NS_WARN_IF(!global)) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  nsCOMPtr<nsIPrincipal> principal =
+    nsContentUtils::ObjectPrincipal(aGlobal.Get());
+
+  nsAutoCString url;
+  aRv = nsHostObjectProtocolHandler::AddDataEntry(aObject, principal, url);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  global->RegisterHostObjectURI(url);
+  CopyASCIItoUTF16(url, aResult);
+}
+
 // The URL implementation for the main-thread
 class URLMainThread final : public URL
 {
 public:
   static already_AddRefed<URLMainThread>
   Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
               URL& aBase, ErrorResult& aRv);
 
@@ -55,44 +79,34 @@ public:
               ErrorResult& aRv);
 
   static void
   CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
                   const objectURLOptions& aOptions, nsAString& aResult,
                   ErrorResult& aRv)
   {
     MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, aBlob.Impl(),
-                            NS_LITERAL_CSTRING(BLOBURI_SCHEME), aOptions,
-                            aResult, aRv);
+    CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
   }
 
   static void
   CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
                   const objectURLOptions& aOptions, nsAString& aResult,
                   ErrorResult& aRv)
   {
     MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, &aStream,
-                            NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME), aOptions,
-                            aResult, aRv);
+    CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
   }
 
   static void
   CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
                   const objectURLOptions& aOptions, nsAString& aResult,
                   ErrorResult& aRv);
 
   static void
-  CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject,
-                          const nsACString& aScheme,
-                          const objectURLOptions& aOptions,
-                          nsAString& aResult, ErrorResult& aRv);
-
-  static void
   RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
                   ErrorResult& aRv);
 
   URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI)
     : URL(aParent)
     , mURI(aURI)
   {
     MOZ_ASSERT(NS_IsMainThread());
@@ -241,62 +255,32 @@ URLMainThread::CreateObjectURL(const Glo
                                nsAString& aResult, ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIPrincipal> principal =
     nsContentUtils::ObjectPrincipal(aGlobal.Get());
 
   nsAutoCString url;
-  aRv = nsHostObjectProtocolHandler::
-    AddDataEntry(NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME),
-                 &aSource, principal, url);
+  aRv = nsHostObjectProtocolHandler::AddDataEntry(&aSource, principal, url);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction(
     [url] {
       nsHostObjectProtocolHandler::RemoveDataEntry(url);
     });
 
   nsContentUtils::RunInStableState(revocation.forget());
 
   CopyASCIItoUTF16(url, aResult);
 }
 
 /* static */ void
-URLMainThread::CreateObjectURLInternal(const GlobalObject& aGlobal,
-                                       nsISupports* aObject,
-                                       const nsACString& aScheme,
-                                       const objectURLOptions& aOptions,
-                                       nsAString& aResult, ErrorResult& aRv)
-{
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  if (!global) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsCOMPtr<nsIPrincipal> principal =
-    nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsAutoCString url;
-  nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject,
-                                                          principal, url);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return;
-  }
-
-  global->RegisterHostObjectURI(url);
-  CopyASCIItoUTF16(url, aResult);
-}
-
-/* static */ void
 URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
                                const nsAString& aURL, ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
   if (!global) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
@@ -821,19 +805,18 @@ public:
 
     DebugOnly<bool> isMutable;
     MOZ_ASSERT(NS_SUCCEEDED(mBlobImpl->GetMutable(&isMutable)));
     MOZ_ASSERT(!isMutable);
 
     nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
 
     nsAutoCString url;
-    nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
-        NS_LITERAL_CSTRING(BLOBURI_SCHEME),
-        mBlobImpl, principal, url);
+    nsresult rv =
+      nsHostObjectProtocolHandler::AddDataEntry(mBlobImpl, principal, url);
 
     if (NS_FAILED(rv)) {
       NS_WARNING("Failed to add data entry for the blob!");
       SetDOMStringToNull(mURL);
       return false;
     }
 
     if (!mWorkerPrivate->IsSharedWorker() &&
deleted file mode 100644
--- a/testing/web-platform/meta/media-source/URL-createObjectURL.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[URL-createObjectURL.html]
-  type: testharness
-  prefs: [media.mediasource.enabled:true]
-  [URL.createObjectURL(mediaSource) should return a unique Blob URI.]
-    expected: FAIL
-