Bug 1457048 - Ensure origins with autoplay-media exact permission can autoplay. r=bryce,r=johannh draft
authorChris Pearce <cpearce@mozilla.com>
Mon, 30 Apr 2018 17:40:50 +1200
changeset 792234 0cb713e80e54627dcfda6838e25c6620e038e627
parent 792233 32179f99a521582026ac5068c3d355dcf4713570
child 792235 65a1c5fa86e0d975e6286931ead03a9349b2f408
push id109052
push userbmo:cpearce@mozilla.com
push dateMon, 07 May 2018 22:26:20 +0000
reviewersbryce, johannh
bugs1457048
milestone61.0a1
Bug 1457048 - Ensure origins with autoplay-media exact permission can autoplay. r=bryce,r=johannh Sites which are whitelisted should be allowed to autoplay audible media. So check whether a HTMLMediaElement's owner doc's principal has an exact "autoplay-media" permission. This ensures whitelisted origins can autoplay, but sub-origins of whitelisted origins need their own permission. MozReview-Commit-ID: 2IO5KIyplEa
browser/modules/SitePermissions.jsm
dom/media/AutoplayPolicy.cpp
dom/media/AutoplayPolicy.h
--- a/browser/modules/SitePermissions.jsm
+++ b/browser/modules/SitePermissions.jsm
@@ -595,16 +595,26 @@ var gPermissionObject = {
    *
    *  - states
    *    Array of permission states to be exposed to the user.
    *    Defaults to ALLOW, BLOCK and the default state (see getDefault).
    *    The PROMPT_HIDE state is deliberately excluded from "plugin:flash" since we
    *    don't want to expose a "Hide Prompt" button to the user through pageinfo.
    */
 
+  "autoplay-media": {
+    exactHostMatch: true,
+    getDefault() {
+      if (Services.prefs.getBoolPref("media.autoplay.enabled")) {
+        return SitePermissions.ALLOW;
+      }
+      return SitePermissions.BLOCK;
+    }
+  },
+
   "image": {
     states: [ SitePermissions.ALLOW, SitePermissions.BLOCK ],
   },
 
   "cookie": {
     states: [ SitePermissions.ALLOW, SitePermissions.ALLOW_COOKIES_FOR_SESSION, SitePermissions.BLOCK ],
     getDefault() {
       if (Services.prefs.getIntPref("network.cookie.cookieBehavior") == 2)
--- a/dom/media/AutoplayPolicy.cpp
+++ b/dom/media/AutoplayPolicy.cpp
@@ -5,29 +5,24 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AutoplayPolicy.h"
 
 #include "mozilla/EventStateManager.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/HTMLMediaElementBinding.h"
+#include "nsContentUtils.h"
 #include "nsIDocument.h"
 #include "MediaManager.h"
 
 namespace mozilla {
 namespace dom {
 
 /* static */ bool
-AutoplayPolicy::IsDocumentAllowedToPlay(nsIDocument* aDoc)
-{
-  return aDoc ? aDoc->HasBeenUserActivated() : false;
-}
-
-/* static */ bool
 AutoplayPolicy::IsMediaElementAllowedToPlay(NotNull<HTMLMediaElement*> aElement)
 {
   if (Preferences::GetBool("media.autoplay.enabled")) {
     return true;
   }
 
   // Pages which have been granted permission to capture WebRTC camera or
   // microphone are assumed to be trusted, and are allowed to autoplay.
@@ -40,27 +35,38 @@ AutoplayPolicy::IsMediaElementAllowedToP
   }
 
   // TODO : this old way would be removed when user-gestures-needed becomes
   // as a default option to block autoplay.
   if (!Preferences::GetBool("media.autoplay.enabled.user-gestures-needed", false)) {
     // If elelement is blessed, it would always be allowed to play().
     return aElement->IsBlessed() ||
            EventStateManager::IsHandlingUserInput();
-   }
+  }
 
   // Muted content
   if (aElement->Volume() == 0.0 || aElement->Muted()) {
     return true;
   }
 
   // Media has already loaded metadata and doesn't contain audio track
   if (aElement->IsVideo() &&
       aElement->ReadyState() >= HTMLMediaElementBinding::HAVE_METADATA &&
       !aElement->HasAudio()) {
     return true;
   }
 
-  return AutoplayPolicy::IsDocumentAllowedToPlay(aElement->OwnerDoc());
+  // Whitelisted.
+  if (nsContentUtils::IsExactSitePermAllow(
+        aElement->NodePrincipal(), "autoplay-media")) {
+    return true;
+  }
+
+  // Activated by user gesture.
+  if (aElement->OwnerDoc()->HasBeenUserActivated()) {
+    return true;
+  }
+
+  return false;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/AutoplayPolicy.h
+++ b/dom/media/AutoplayPolicy.h
@@ -20,22 +20,21 @@ class HTMLMediaElement;
  * AutoplayPolicy is used to manage autoplay logic for all kinds of media,
  * including MediaElement, Web Audio and Web Speech.
  *
  * Autoplay could be disable by turn off the pref "media.autoplay.enabled".
  * Once user disable autoplay, media could only be played if one of following
  * conditions is true.
  * 1) Owner document is activated by user gestures
  *    We restrict user gestures to "mouse click", "keyboard press" and "touch".
- * 2) Muted media content or video without audio content
+ * 2) Muted media content or video without audio content.
+ * 3) Document's origin has the "autoplay-media" permission.
  */
 class AutoplayPolicy
 {
 public:
   static bool IsMediaElementAllowedToPlay(NotNull<HTMLMediaElement*> aElement);
-private:
-  static bool IsDocumentAllowedToPlay(nsIDocument* aDoc);
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
\ No newline at end of file