Bug 654550 - Add a preference to disable media statistics. r = padenot,jaws
authorLéonard Beck <leonard.beck@gmail.com>
Tue, 11 Jun 2013 17:23:13 +0200
changeset 136495 8710fcb40a3219a9b9d5646a110b3e50413bcbab
parent 136494 6a4a979ca127e053d5e25049137fa4418aa1cce1
child 136496 a4f84868850fbc05e526bc2a61c2974f033d0186
push id24884
push useremorley@mozilla.com
push dateWed, 26 Jun 2013 14:10:39 +0000
treeherdermozilla-central@c3598b276048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs654550
milestone25.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 654550 - Add a preference to disable media statistics. r = padenot,jaws
content/html/content/public/HTMLVideoElement.h
content/html/content/src/HTMLVideoElement.cpp
content/media/test/Makefile.in
content/media/test/manifest.js
content/media/test/test_bug654550.html
layout/build/nsLayoutStatics.cpp
modules/libpref/src/init/all.js
--- a/content/html/content/public/HTMLVideoElement.h
+++ b/content/html/content/public/HTMLVideoElement.h
@@ -42,16 +42,19 @@ public:
   // nsIDOMHTMLVideoElement
   NS_DECL_NSIDOMHTMLVIDEOELEMENT
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult);
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
+
+  static void Init();
+
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // Set size with the current video frame's height and width.
   // If there is no video frame, returns NS_ERROR_FAILURE.
   nsresult GetVideoSize(nsIntSize* size);
 
--- a/content/html/content/src/HTMLVideoElement.cpp
+++ b/content/html/content/src/HTMLVideoElement.cpp
@@ -28,22 +28,25 @@
 
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMProgressEvent.h"
 #include "nsIPowerManagerService.h"
 #include "MediaError.h"
 #include "MediaDecoder.h"
+#include "mozilla/Preferences.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Video)
 
 namespace mozilla {
 namespace dom {
 
+static bool sVideoStatsEnabled;
+
 NS_IMPL_ADDREF_INHERITED(HTMLVideoElement, HTMLMediaElement)
 NS_IMPL_RELEASE_INHERITED(HTMLVideoElement, HTMLMediaElement)
 
 NS_INTERFACE_TABLE_HEAD(HTMLVideoElement)
   NS_HTML_CONTENT_INTERFACES(HTMLMediaElement)
   NS_INTERFACE_TABLE_INHERITED2(HTMLVideoElement, nsIDOMHTMLMediaElement, nsIDOMHTMLVideoElement)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE
 NS_ELEMENT_INTERFACE_MAP_END
@@ -155,52 +158,64 @@ nsresult HTMLVideoElement::SetAcceptHead
                                     false);
 }
 
 NS_IMPL_URI_ATTR(HTMLVideoElement, Poster, poster)
 
 uint32_t HTMLVideoElement::MozParsedFrames() const
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
+  if (!sVideoStatsEnabled) {
+    return 0;
+  }
   return mDecoder ? mDecoder->GetFrameStatistics().GetParsedFrames() : 0;
 }
 
 NS_IMETHODIMP HTMLVideoElement::GetMozParsedFrames(uint32_t *aMozParsedFrames)
 {
   *aMozParsedFrames = MozParsedFrames();
   return NS_OK;
 }
 
 uint32_t HTMLVideoElement::MozDecodedFrames() const
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
+  if (!sVideoStatsEnabled) {
+    return 0;
+  }
   return mDecoder ? mDecoder->GetFrameStatistics().GetDecodedFrames() : 0;
 }
 
 NS_IMETHODIMP HTMLVideoElement::GetMozDecodedFrames(uint32_t *aMozDecodedFrames)
 {
   *aMozDecodedFrames = MozDecodedFrames();
   return NS_OK;
 }
 
 uint32_t HTMLVideoElement::MozPresentedFrames() const
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
+  if (!sVideoStatsEnabled) {
+    return 0;
+  }
   return mDecoder ? mDecoder->GetFrameStatistics().GetPresentedFrames() : 0;
 }
 
 NS_IMETHODIMP HTMLVideoElement::GetMozPresentedFrames(uint32_t *aMozPresentedFrames)
 {
   *aMozPresentedFrames = MozPresentedFrames();
   return NS_OK;
 }
 
 uint32_t HTMLVideoElement::MozPaintedFrames()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
+  if (!sVideoStatsEnabled) {
+    return 0;
+  }
   layers::ImageContainer* container = GetImageContainer();
   return container ? container->GetPaintCount() : 0;
 }
 
 NS_IMETHODIMP HTMLVideoElement::GetMozPaintedFrames(uint32_t *aMozPaintedFrames)
 {
   *aMozPaintedFrames = MozPaintedFrames();
   return NS_OK;
@@ -277,10 +292,15 @@ HTMLVideoElement::WakeLockUpdate()
     NS_ENSURE_TRUE_VOID(pmService);
 
     pmService->NewWakeLock(NS_LITERAL_STRING("screen"),
                            OwnerDoc()->GetWindow(),
                            getter_AddRefs(mScreenWakeLock));
   }
 }
 
+void
+HTMLVideoElement::Init()
+{
+  Preferences::AddBoolVarCache(&sVideoStatsEnabled, "media.video_stats.enabled");
+}
 } // namespace dom
 } // namespace mozilla
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -67,16 +67,17 @@ MOCHITEST_FILES = \
 		test_access_control.html \
 		test_audio1.html \
 		test_audio2.html \
 		test_autoplay.html \
 		test_bug465498.html \
 		test_bug493187.html \
 		test_bug495145.html \
 		test_bug495300.html \
+		test_bug654550.html \
 		test_bug686942.html \
 		test_can_play_type.html \
 		test_can_play_type_mpeg.html \
 		test_closing_connections.html \
 		test_constants.html \
 		test_controls.html \
 		test_currentTime.html \
 		test_decode_error.html \
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -11,16 +11,23 @@ var gSmallTests = [
   { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
   { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 },
   { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 },
   { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
   { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
   { name:"bogus.duh", type:"bogus/duh" }
 ];
 
+// Used by test_bug654550.html, for videoStats preference
+var gVideoTests = [
+  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 },
+  { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 },
+  { name:"bogus.duh", type:"bogus/duh" }
+];
+
 // Used by test_progress to ensure we get the correct progress information
 // during resource download.
 var gProgressTests = [
   { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0, size:11069 },
   { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 },
   { name:"seek.ogv", type:"video/ogg", duration:3.966, size:285310 },
   { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, size:28942 },
   { name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_bug654550.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=654550
+-->
+
+<head>
+  <title>Test for Bug 654550</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=654550">Mozilla Bug 654550</a>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+  /* Test for Bug 654550 */
+
+  var manager = new MediaTestManager;
+
+  function checkStats(v, aShouldBeEnabled) {
+    if (aShouldBeEnabled) {
+      ok(v.mozParsedFrames != 0,
+         "At least one value should be different from 0 if stats are enabled");
+    } else {
+      ok(!v.mozParsedFrames,
+        "mozParsedFrames should be 0 if stats are disabled");
+      ok(!v.mozDecodedFrames,
+        "mozDecodedFrames should be 0 if stats are disabled");
+      ok(!v.mozPresentedFrames,
+        "mozPresentedFrames should be 0 if stats are disabled");
+      ok(!v.mozPaintedFrames,
+        "mozPaintedFrames should be 0 if stats are disabled");
+    }
+
+  }
+
+  function ontimeupdate(event) {
+    var v = event.target;
+    if (SpecialPowers.getBoolPref("media.video_stats.enabled")) {
+      checkStats(v, true);
+      SpecialPowers.setBoolPref("media.video_stats.enabled", false);
+    } else {
+      checkStats(v, false);
+      SpecialPowers.setBoolPref("media.video_stats.enabled", true);
+      v.removeEventListener("timeupdate", ontimeupdate);
+      SpecialPowers.clearUserPref("media.video_stats.enabled");
+      manager.finished(v.token);
+    }
+  }
+
+
+  function startTest(test, token) {
+    var v = document.createElement('video');
+    v.token = token;
+    v.src = test.name;
+    manager.started(token);
+    v.play();
+    SpecialPowers.setBoolPref("media.video_stats.enabled", true);
+    v.addEventListener("timeupdate", ontimeupdate);
+    SimpleTest.waitForExplicitFinish();
+  }
+
+  manager.runTests(gVideoTests, startTest);
+
+</script>
+</pre>
+</body>
+</html>
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -111,16 +111,17 @@ using namespace mozilla::system;
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/ProcessPriorityManager.h"
 #include "nsPermissionManager.h"
 #include "nsCookieService.h"
 #include "nsApplicationCacheService.h"
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "nsIMEStateManager.h"
 #include "nsDocument.h"
+#include "mozilla/dom/HTMLVideoElement.h"
 
 extern void NS_ShutdownEventTargetChainItemRecyclePool();
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::dom::time;
 
@@ -267,16 +268,18 @@ nsLayoutStatics::Initialize()
   ProcessPriorityManager::Init();
 
   nsPermissionManager::AppClearDataObserverInit();
   nsCookieService::AppClearDataObserverInit();
   nsApplicationCacheService::AppClearDataObserverInit();
 
   InitializeDateCacheCleaner();
 
+  HTMLVideoElement::Init();
+
   return NS_OK;
 }
 
 void
 nsLayoutStatics::Shutdown()
 {
   // Don't need to shutdown nsWindowMemoryReporter, that will be done by the
   // memory reporter manager.
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -227,16 +227,19 @@ pref("media.webaudio.enabled", false);
 
 // Whether to autostart a media element with an |autoplay| attribute
 pref("media.autoplay.enabled", true);
 
 // The default number of decoded video frames that are enqueued in
 // MediaDecoderReader's mVideoQueue.
 pref("media.video-queue.default-size", 10);
 
+// Whether to disable the video stats to prevent fingerprinting
+pref("media.video_stats.enabled", true);
+
 // Whether to enable the audio writing APIs on the audio element
 pref("media.audio_data.enabled", true);
 
 #ifdef XP_MACOSX
 // Whether to run in native HiDPI mode on machines with "Retina"/HiDPI display;
 //   <= 0 : hidpi mode disabled, display will just use pixel-based upscaling
 //   == 1 : hidpi supported if all screens share the same backingScaleFactor
 //   >= 2 : hidpi supported even with mixed backingScaleFactors (somewhat broken)