Bug 1112761 part 2. Enable MediaSource based on a whitelist, not in general. r=kinetik
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 08 Jan 2015 11:57:11 -0500
changeset 222797 37bd1af93c544eeb6134378e6b574a560b5a9bfe
parent 222796 4a03e62bd2d23fd9c82980a2fba8808c638074aa
child 222798 23ce8a6e826fbd6fd284b1db9bb37633e623b9bf
push id28073
push userkwierso@gmail.com
push dateFri, 09 Jan 2015 01:08:23 +0000
treeherdermozilla-central@b3f84cf78dc2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1112761
milestone37.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 1112761 part 2. Enable MediaSource based on a whitelist, not in general. r=kinetik
dom/media/mediasource/MediaSource.cpp
dom/media/mediasource/test/crashtests/1005366.html
dom/media/mediasource/test/crashtests/1059035.html
dom/media/mediasource/test/crashtests/crashtests.list
dom/media/mediasource/test/mediasource.js
dom/media/mediasource/test/test_MediaSource_disabled.html
dom/media/test/test_VideoPlaybackQuality.html
dom/media/test/test_VideoPlaybackQuality_disabled.html
dom/media/test/test_eme_canvas_blocked.html
dom/media/test/test_eme_playback.html
dom/media/test/test_eme_requestKeySystemAccess.html
dom/media/test/test_eme_stream_capture_blocked.html
modules/libpref/init/all.js
testing/profiles/prefs_general.js
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -14,20 +14,24 @@
 #include "mozilla/ErrorResult.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "mozilla/mozalloc.h"
 #include "nsContentTypeParser.h"
+#include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsError.h"
+#include "nsIEffectiveTLDService.h"
 #include "nsIRunnable.h"
 #include "nsIScriptObjectPrincipal.h"
+#include "nsIURI.h"
+#include "nsNetCID.h"
 #include "nsPIDOMWindow.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "prlog.h"
 
 struct JSContext;
 class JSObject;
 
@@ -304,17 +308,54 @@ MediaSource::IsTypeSupported(const Globa
   MSE_API("MediaSource::IsTypeSupported(aType=%s)%s",
           NS_ConvertUTF16toUTF8(aType).get(), rv == NS_OK ? "" : " [not supported]");
   return NS_SUCCEEDED(rv);
 }
 
 /* static */ bool
 MediaSource::Enabled(JSContext* cx, JSObject* aGlobal)
 {
-  return Preferences::GetBool("media.mediasource.enabled");
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // Don't use aGlobal across Preferences stuff, which the static
+  // analysis thinks can GC.
+  JS::Rooted<JSObject*> global(cx, aGlobal);
+
+  bool enabled = Preferences::GetBool("media.mediasource.enabled");
+  if (!enabled) {
+    return false;
+  }
+
+  // Check whether it's enabled everywhere or just YouTube.
+  bool restrict = Preferences::GetBool("media.mediasource.youtubeonly", false);
+  if (!restrict) {
+    return true;
+  }
+
+  // We want to restrict to YouTube only.  We define that as the
+  // origin being https://*.youtube.com.
+  nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(global);
+  nsCOMPtr<nsIURI> uri;
+  if (NS_FAILED(principal->GetURI(getter_AddRefs(uri))) || !uri) {
+    return false;
+  }
+
+  bool isHttps = false;
+  if (NS_FAILED(uri->SchemeIs("https", &isHttps)) || !isHttps) {
+    return false;
+  }
+
+  nsCOMPtr<nsIEffectiveTLDService> tldServ =
+    do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
+  NS_ENSURE_TRUE(tldServ, false);
+
+  nsAutoCString eTLDplusOne;
+  return
+    NS_SUCCEEDED(tldServ->GetBaseDomain(uri, 0, eTLDplusOne)) &&
+    eTLDplusOne.EqualsLiteral("youtube.com");
 }
 
 bool
 MediaSource::Attach(MediaSourceDecoder* aDecoder)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MSE_DEBUG("MediaSource(%p)::Attach(aDecoder=%p) owner=%p", this, aDecoder, aDecoder->GetOwner());
   MOZ_ASSERT(aDecoder);
--- a/dom/media/mediasource/test/crashtests/1005366.html
+++ b/dom/media/mediasource/test/crashtests/1005366.html
@@ -1,16 +1,17 @@
 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8">
 <script>
 
 /*
 user_pref("media.mediasource.enabled", true);
+user_pref("media.mediasource.youtubeonly", false);
 */
 
 function boom()
 {
     var source = new window.MediaSource();
     var videoElement = document.createElementNS('http://www.w3.org/1999/xhtml', 'video');
     videoElement.src = URL.createObjectURL(source);
 
--- a/dom/media/mediasource/test/crashtests/1059035.html
+++ b/dom/media/mediasource/test/crashtests/1059035.html
@@ -1,15 +1,16 @@
 <!DOCTYPE html>
 <html>
 <head>
 <script>
 
 /*
 user_pref("media.mediasource.enabled", true);
+user_pref("media.mediasource.youtubeonly", false);
 */
 
 function boom()
 {
     var mediaSource = new MediaSource();
     var htmlAudio = document.createElement("audio");
     htmlAudio.src = URL.createObjectURL(mediaSource);
 
--- a/dom/media/mediasource/test/crashtests/crashtests.list
+++ b/dom/media/mediasource/test/crashtests/crashtests.list
@@ -1,4 +1,4 @@
-test-pref(media.mediasource.enabled,true) load 926665.html
-test-pref(media.mediasource.enabled,true) load 931388.html
-test-pref(media.mediasource.enabled,true) load 1005366.html
-test-pref(media.mediasource.enabled,true) load 1059035.html
+test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 926665.html
+test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 931388.html
+test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 1005366.html
+test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 1059035.html
--- a/dom/media/mediasource/test/mediasource.js
+++ b/dom/media/mediasource/test/mediasource.js
@@ -12,17 +12,20 @@ function runWithMSE(testFunction) {
     SimpleTest.registerCleanupFunction(function () {
       el.parentNode.removeChild(el);
     });
 
     testFunction(ms, el);
   }
 
   addLoadEvent(function () {
-    SpecialPowers.pushPrefEnv({"set": [[ "media.mediasource.enabled", true ]]},
+    SpecialPowers.pushPrefEnv({"set": [
+	[ "media.mediasource.enabled", true ],
+	[ "media.mediasource.youtubeonly", false ],
+    ]},
                               bootstrapTest);
   });
 }
 
 function fetchWithXHR(uri, onLoadFunction) {
   var xhr = new XMLHttpRequest();
   xhr.open("GET", uri, true);
   xhr.responseType = "arraybuffer";
--- a/dom/media/mediasource/test/test_MediaSource_disabled.html
+++ b/dom/media/mediasource/test/test_MediaSource_disabled.html
@@ -14,15 +14,20 @@ SimpleTest.waitForExplicitFinish();
 function test() {
   ok(!window.MediaSource && !window.SourceBuffer && !window.SourceBufferList,
      "MediaSource should be hidden behind a pref");
   SimpleTest.doesThrow(() => new MediaSource,
                        "MediaSource should be hidden behind a pref");
   SimpleTest.finish();
 }
 
-SpecialPowers.pushPrefEnv({"set": [["media.mediasource.enabled", false]]},
+SpecialPowers.pushPrefEnv({"set":
+    [
+      ["media.mediasource.enabled", false],
+      ["media.mediasource.youtubeonly", false],
+    ]
+  },
                           test);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_VideoPlaybackQuality.html
+++ b/dom/media/test/test_VideoPlaybackQuality.html
@@ -46,14 +46,19 @@ function test() {
       is(vpq.corruptedVideoFrames, 0, "corruptedVideoFrames should be 0");
 
       SimpleTest.finish();
     });
   });
 }
 
 addLoadEvent(function() {
-  SpecialPowers.pushPrefEnv({"set": [["media.mediasource.enabled", true]]}, test);
+  SpecialPowers.pushPrefEnv({"set":
+    [
+      ["media.mediasource.enabled", true],
+      ["media.mediasource.youtubeonly", false],
+    ]
+  }, test);
 });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_VideoPlaybackQuality_disabled.html
+++ b/dom/media/test/test_VideoPlaybackQuality_disabled.html
@@ -20,14 +20,19 @@ function test() {
   } catch (e) {
     accessThrows = true;
   }
   ok(accessThrows, "getVideoPlaybackQuality should be hidden behind a pref");
   SimpleTest.finish();
 }
 
 addLoadEvent(function() {
-  SpecialPowers.pushPrefEnv({"set": [["media.mediasource.enabled", false]]}, test);
+  SpecialPowers.pushPrefEnv({"set":
+    [
+     ["media.mediasource.enabled", false],
+     ["media.mediasource.youtubeonly", false],
+    ]
+  }, test);
 });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_eme_canvas_blocked.html
+++ b/dom/media/test/test_eme_canvas_blocked.html
@@ -44,16 +44,17 @@ function startTest(test, token)
 }
 
 function beginTest() {
   manager.runTests(gEMETests, startTest);
 }
 
 var prefs = [
   [ "media.mediasource.enabled", true ],
+  [ "media.mediasource.youtubeonly", false ],
   [ "media.mediasource.mp4.enabled", true ],
 ];
 
 if (/Linux/.test(navigator.userAgent) ||
     !document.createElement('video').canPlayType("video/mp4")) {
   // XXX remove once we have mp4 PlatformDecoderModules on all platforms.
   prefs.push([ "media.fragmented-mp4.exposed", true ]);
   prefs.push([ "media.fragmented-mp4.use-blank-decoder", true ]);
--- a/dom/media/test/test_eme_playback.html
+++ b/dom/media/test/test_eme_playback.html
@@ -87,16 +87,17 @@ function startTest(test, token)
 }
 
 function beginTest() {
   manager.runTests(gEMETests, startTest);
 }
 
 var prefs = [
   [ "media.mediasource.enabled", true ],
+  [ "media.mediasource.youtubeonly", false ],
   [ "media.mediasource.mp4.enabled", true ],
 ];
 
 if (/Linux/.test(navigator.userAgent) ||
     !document.createElement('video').canPlayType("video/mp4")) {
   // XXX remove once we have mp4 PlatformDecoderModules on all platforms.
   prefs.push([ "media.fragmented-mp4.exposed", true ]);
   prefs.push([ "media.fragmented-mp4.use-blank-decoder", true ]);
--- a/dom/media/test/test_eme_requestKeySystemAccess.html
+++ b/dom/media/test/test_eme_requestKeySystemAccess.html
@@ -269,16 +269,17 @@ var tests = [
 ];
 
 function beginTest() {
   Promise.all(tests.map(Test)).then(function() { SimpleTest.finish(); });
 }
 
 var prefs = [
   [ "media.mediasource.enabled", true ],
+  [ "media.mediasource.youtubeonly", false ],
   [ "media.mediasource.mp4.enabled", true ],
 ];
 
 if (/Linux/.test(navigator.userAgent) ||
     !document.createElement('video').canPlayType("video/mp4")) {
   // XXX remove once we have mp4 PlatformDecoderModules on all platforms.
   prefs.push([ "media.fragmented-mp4.exposed", true ]);
   prefs.push([ "media.fragmented-mp4.use-blank-decoder", true ]);
--- a/dom/media/test/test_eme_stream_capture_blocked.html
+++ b/dom/media/test/test_eme_stream_capture_blocked.html
@@ -76,16 +76,17 @@ function startTest(test, token)
 }
 
 function beginTest() {
   manager.runTests(gEMETests, startTest);
 }
 
 var prefs = [
   [ "media.mediasource.enabled", true ],
+  [ "media.mediasource.youtubeonly", false ],
   [ "media.mediasource.mp4.enabled", true ],
 ];
 
 if (/Linux/.test(navigator.userAgent) ||
     !document.createElement('video').canPlayType("video/mp4")) {
   // XXX remove once we have mp4 PlatformDecoderModules on all platforms.
   prefs.push([ "media.fragmented-mp4.exposed", true ]);
   prefs.push([ "media.fragmented-mp4.use-blank-decoder", true ]);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -423,22 +423,31 @@ pref("media.getusermedia.screensharing.a
 
 // TextTrack support
 pref("media.webvtt.enabled", true);
 pref("media.webvtt.regions.enabled", false);
 
 // AudioTrack and VideoTrack support
 pref("media.track.enabled", false);
 
-// Whether to enable MediaSource support
-#ifdef RELEASE_BUILD
+// Whether to enable MediaSource support.  We want to enable on non-release
+// builds and on release windows, but on release builds restrict to YouTube.  We
+// don't enable for YouTube on non-Windows for now because the MP4 code for
+// those platforms isn't ready yet.
+#if defined(XP_WIN) || !defined(RELEASE_BUILD)
+pref("media.mediasource.enabled", true);
+#else
 pref("media.mediasource.enabled", false);
+#endif
+
+#ifdef RELEASE_BUILD
+pref("media.mediasource.youtubeonly", true);
 #else
-pref("media.mediasource.enabled", true);
-#endif
+pref("media.mediasource.youtubeonly", false);
+#endif // RELEASE_BUILD
 
 #ifdef MOZ_WIDGET_GONK
 pref("media.mediasource.mp4.enabled", false);
 pref("media.mediasource.webm.enabled", false);
 #else
 #if defined(XP_WIN) || defined(XP_MACOSX)
 pref("media.mediasource.mp4.enabled", true);
 pref("media.mediasource.webm.enabled", false);
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -152,16 +152,17 @@ user_pref("layout.css.ruby.enabled", tru
 // Enable CSS Font Loading API for testing
 user_pref("layout.css.font-loading-api.enabled", true);
 
 // Disable spammy layout warnings because they pollute test logs
 user_pref("layout.spammy_warnings.enabled", false);
 
 // Enable Media Source Extensions for testing
 user_pref("media.mediasource.enabled", true);
+user_pref("media.mediasource.youtubeonly", false);
 user_pref("media.mediasource.mp4.enabled", true);
 user_pref("media.mediasource.webm.enabled", true);
 
 // Enable mozContacts
 user_pref("dom.mozContacts.enabled", true);
 
 // Enable mozSettings
 user_pref("dom.mozSettings.enabled", true);