Bug 1519430 - part2 : only resume AudioContext which is blocked by autoplay policy. r=padenot
☠☠ backed out by eff7fd1e573c ☠ ☠
authorAlastor Wu <alwu@mozilla.com>
Thu, 17 Jan 2019 02:58:03 +0000
changeset 511341 987aa2594ba62b25ca9a36ae51e8c4d7afb0939e
parent 511340 521176ad7ae8c205307c4447c70a4de546c6cac8
child 511342 b7bc38b0f9c5614fb4fd5edf7e4686c9b3b0d179
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1519430
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 1519430 - part2 : only resume AudioContext which is blocked by autoplay policy. r=padenot We would only start the AudioContext blocked by our autoplay policy, won't resume AudioContext which is suspended explictly by page. Differential Revision: https://phabricator.services.mozilla.com/D16613
dom/media/webaudio/AudioContext.cpp
dom/media/webaudio/AudioContext.h
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -148,16 +148,17 @@ AudioContext::AudioContext(nsPIDOMWindow
       mNumberOfChannels(aNumberOfChannels),
       mIsOffline(aIsOffline),
       mIsStarted(!aIsOffline),
       mIsShutDown(false),
       mCloseCalled(false),
       mSuspendCalled(false),
       mIsDisconnecting(false),
       mWasAllowedToStart(true),
+      mSuspendedByContent(false),
       mWasEverAllowedToStart(false),
       mWasEverBlockedToStart(false),
       mWouldBeAllowedToStart(true) {
   bool mute = aWindow->AddAudioContext(this);
 
   // Note: AudioDestinationNode needs an AudioContext that must already be
   // bound to the window.
   const bool allowedToStart = AutoplayPolicy::IsAllowedToPlay(*this);
@@ -188,17 +189,21 @@ void AudioContext::StartBlockedAudioCont
   // Only try to start AudioContext when AudioContext was not allowed to start.
   if (mWasAllowedToStart) {
     return;
   }
 
   const bool isAllowedToPlay = AutoplayPolicy::IsAllowedToPlay(*this);
   AUTOPLAY_LOG("Trying to start AudioContext %p, IsAllowedToPlay=%d", this,
                isAllowedToPlay);
-  if (isAllowedToPlay) {
+
+  // Only start the AudioContext if this resume() call was initiated by content,
+  // not if it was a result of the AudioContext starting after having been
+  // blocked because of the auto-play policy.
+  if (isAllowedToPlay && !mSuspendedByContent) {
     ResumeInternal();
   } else {
     ReportBlocked();
   }
 }
 
 nsresult AudioContext::Init() {
   if (!mIsOffline) {
@@ -897,16 +902,17 @@ already_AddRefed<Promise> AudioContext::
     return promise.forget();
   }
 
   if (mAudioContextState == AudioContextState::Closed || mCloseCalled) {
     promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     return promise.forget();
   }
 
+  mSuspendedByContent = true;
   mPromiseGripArray.AppendElement(promise);
   SuspendInternal(promise);
   return promise.forget();
 }
 
 void AudioContext::SuspendFromChrome() {
   // Not support suspend call for these situations.
   if (mAudioContextState == AudioContextState::Suspended ||
@@ -957,16 +963,17 @@ already_AddRefed<Promise> AudioContext::
     return promise.forget();
   }
 
   if (mAudioContextState == AudioContextState::Closed || mCloseCalled) {
     promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     return promise.forget();
   }
 
+  mSuspendedByContent = false;
   mPendingResumePromises.AppendElement(promise);
 
   const bool isAllowedToPlay = AutoplayPolicy::IsAllowedToPlay(*this);
   AUTOPLAY_LOG("Trying to resume AudioContext %p, IsAllowedToPlay=%d", this,
                isAllowedToPlay);
   if (isAllowedToPlay) {
     ResumeInternal();
   } else {
--- a/dom/media/webaudio/AudioContext.h
+++ b/dom/media/webaudio/AudioContext.h
@@ -381,16 +381,19 @@ class AudioContext final : public DOMEve
   // Close has been called, reject suspend and resume call.
   bool mCloseCalled;
   // Suspend has been called with no following resume.
   bool mSuspendCalled;
   bool mIsDisconnecting;
   // This flag stores the value of previous status of `allowed-to-start`.
   bool mWasAllowedToStart;
 
+  // True if this AudioContext has been suspended by the page.
+  bool mSuspendedByContent;
+
   // These variables are used for telemetry, they're not reflect the actual
   // status of AudioContext, they are based on the "assumption" of enabling
   // blocking web audio. Because we want to record Telemetry no matter user
   // enable blocking autoplay or not.
   // - 'mWasEverAllowedToStart' would be true when AudioContext had ever been
   //   allowed to start if we enable blocking web audio.
   // - 'mWasEverBlockedToStart' would be true when AudioContext had ever been
   //   blocked to start if we enable blocking web audio.