Bug 1506290 - part1 : implement 'document.autoplayPolicy'. r=baku,cpearce
authoralwu <alwu@mozilla.com>
Tue, 15 Jan 2019 00:13:34 +0000
changeset 513875 63c3828351f0
parent 513874 ea8b794f04d8
child 513876 3420cf8f79a9
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, cpearce
bugs1506290
milestone66.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 1506290 - part1 : implement 'document.autoplayPolicy'. r=baku,cpearce `document.autoplayPolicy` returns a enum string that can change overtime based on user session activity: - “allowed” if autoplay is currently allowed. - “allowed-muted” if muted video autoplay is currently allowed. - “disallowed” is autoplay is not current allowed. Differential Revision: https://phabricator.services.mozilla.com/D11543
dom/base/Document.cpp
dom/base/Document.h
dom/media/AutoplayPolicy.cpp
dom/media/AutoplayPolicy.h
dom/webidl/Document.webidl
modules/libpref/init/StaticPrefList.h
modules/libpref/init/all.js
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -279,16 +279,17 @@
 #include "mozilla/DocLoadingTimelineMarker.h"
 
 #include "mozilla/dom/WindowGlobalChild.h"
 
 #include "nsISpeculativeConnect.h"
 
 #include "mozilla/MediaManager.h"
 
+#include "AutoplayPolicy.h"
 #include "nsIURIMutator.h"
 #include "mozilla/DocumentStyleRootIterator.h"
 #include "mozilla/PendingFullscreenEvent.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "nsHTMLTags.h"
 #include "NodeUbiReporting.h"
 #include "nsICookieService.h"
@@ -11726,16 +11727,20 @@ void Document::SetDocTreeHadAudibleMedia
 
 void Document::SetDocTreeHadPlayRevoked() {
   Document* topLevelDoc = GetTopLevelContentDocument();
   if (topLevelDoc) {
     topLevelDoc->mDocTreeHadPlayRevoked = true;
   }
 }
 
+DocumentAutoplayPolicy Document::AutoplayPolicy() const {
+  return AutoplayPolicy::IsAllowedToPlay(*this);
+}
+
 void Document::MaybeAllowStorageForOpenerAfterUserInteraction() {
   if (StaticPrefs::network_cookie_cookieBehavior() !=
       nsICookieService::BEHAVIOR_REJECT_TRACKER) {
     return;
   }
 
   // This will probably change for project fission, but currently this document
   // and the opener are on the same process. In the future, we should make this
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -3282,16 +3282,20 @@ class Document : public nsINode,
   void PropagateUseCounters(Document* aParentDocument);
 
   // Called to track whether this document has had any interaction.
   // This is used to track whether we should permit "beforeunload".
   void SetUserHasInteracted();
   bool UserHasInteracted() { return mUserHasInteracted; }
   void ResetUserInteractionTimer();
 
+  // This method would return current autoplay policy, it would be "allowed"
+  // , "allowed-muted" or "disallowed".
+  mozilla::dom::DocumentAutoplayPolicy AutoplayPolicy() const;
+
   // This should be called when this document receives events which are likely
   // to be user interaction with the document, rather than the byproduct of
   // interaction with the browser (i.e. a keypress to scroll the view port,
   // keyboard shortcuts, etc). This is used to decide whether we should
   // permit autoplay audible media. This also gesture activates all other
   // content documents in this tab.
   void NotifyUserGestureActivation();
 
--- a/dom/media/AutoplayPolicy.cpp
+++ b/dom/media/AutoplayPolicy.cpp
@@ -204,10 +204,24 @@ static bool IsEnableBlockingWebAudioByUs
     const AudioContext& aContext) {
   if (!IsEnableBlockingWebAudioByUserGesturePolicy()) {
     return true;
   }
 
   return IsAudioContextAllowedToPlay(aContext);
 }
 
+/* static */ DocumentAutoplayPolicy AutoplayPolicy::IsAllowedToPlay(
+    const Document& aDocument) {
+  if (DefaultAutoplayBehaviour() == nsIAutoplay::ALLOWED ||
+      IsWindowAllowedToPlay(aDocument.GetInnerWindow())) {
+    return DocumentAutoplayPolicy::Allowed;
+  }
+
+  if (StaticPrefs::MediaAutoplayAllowMuted()) {
+    return DocumentAutoplayPolicy::Allowed_muted;
+  }
+
+  return DocumentAutoplayPolicy::Disallowed;
+}
+
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/media/AutoplayPolicy.h
+++ b/dom/media/AutoplayPolicy.h
@@ -25,16 +25,19 @@ class Document;
  * 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.
  * 3) Document's origin has the "autoplay-media" permission.
  */
 class AutoplayPolicy {
  public:
+  // Returns a DocumentAutoplayPolicy for given document.
+  static DocumentAutoplayPolicy IsAllowedToPlay(const Document& aDocument);
+
   // Returns whether a given media element is allowed to play.
   static bool IsAllowedToPlay(const HTMLMediaElement& aElement);
 
   // Returns whether a given AudioContext is allowed to play.
   static bool IsAllowedToPlay(const AudioContext& aContext);
 
   // Returns true if a given media element would be allowed to play
   // if block autoplay was enabled. If this returns false, it means we would
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -487,16 +487,28 @@ partial interface Document {
 // https://github.com/whatwg/html/issues/3338
 partial interface Document {
   [Pref="dom.storage_access.enabled", Throws]
   Promise<boolean> hasStorageAccess();
   [Pref="dom.storage_access.enabled", Throws]
   Promise<void> requestStorageAccess();
 };
 
+enum DocumentAutoplayPolicy {
+  "allowed",       // autoplay is currently allowed
+  "allowed-muted", // muted video autoplay is currently allowed
+  "disallowed"     // autoplay is not current allowed
+};
+
+// https://github.com/WICG/autoplay/issues/1
+partial interface Document {
+  [Pref="dom.media.autoplay.autoplay-policy-api"]
+  readonly attribute DocumentAutoplayPolicy autoplayPolicy;
+};
+
 // Extension to give chrome JS the ability to determine whether
 // the user has interacted with the document or not.
 partial interface Document {
   [ChromeOnly] readonly attribute boolean userHasInteracted;
 };
 
 // Extension to give chrome JS the ability to simulate activate the docuement
 // by user gesture.
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -1593,16 +1593,22 @@ VARCACHE_PREF(
 )
 
 VARCACHE_PREF(
   "media.test.video-suspend",
    MediaTestVideoSuspend,
   RelaxedAtomicBool, false
 )
 
+VARCACHE_PREF(
+  "media.autoplay.allow-muted",
+   MediaAutoplayAllowMuted,
+  RelaxedAtomicBool, true
+)
+
 //---------------------------------------------------------------------------
 // Network prefs
 //---------------------------------------------------------------------------
 
 // Sub-resources HTTP-authentication:
 //   0 - don't allow sub-resources to open HTTP authentication credentials
 //       dialogs
 //   1 - allow sub-resources to open HTTP authentication credentials dialogs,
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -614,16 +614,21 @@ pref("media.autoplay.enabled.user-gestur
 // HTMLMediaElement.allowedToPlay should be exposed to web content when
 // block autoplay rides the trains to release. Until then, Nightly only.
 #ifdef NIGHTLY_BUILD
 pref("media.allowed-to-play.enabled", true);
 #else
 pref("media.allowed-to-play.enabled", false);
 #endif
 
+// This pref is used to enable/disable the `document.autoplayPolicy` API which
+// returns a enum string which presents current autoplay policy and can change
+// overtime based on user session activity.
+pref("dom.media.autoplay.autoplay-policy-api", false);
+
 // The default number of decoded video frames that are enqueued in
 // MediaDecoderReader's mVideoQueue.
 pref("media.video-queue.default-size", 10);
 
 // The maximum number of queued frames to send to the compositor.
 // By default, send all of them.
 pref("media.video-queue.send-to-compositor-size", 9999);