Bug 1519430 - part1 : add new methods for calling suspend/resume from chrome. r=padenot
authorAlastor Wu <alwu@mozilla.com>
Fri, 18 Jan 2019 18:35:07 +0000
changeset 454510 737577f837bce6bb2460b0cadbf3143a66b65f44
parent 454509 b86c22898543ba5cefed5b453af7ef46dcc1dfb5
child 454511 ebe7d324f3b2a546cb4745c6a6dfdca0b6a6ff11
push id35399
push usercsabou@mozilla.com
push dateSat, 19 Jan 2019 09:28:26 +0000
treeherdermozilla-central@64d167665c29 [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 - part1 : add new methods for calling suspend/resume from chrome. r=padenot In order to separate resume/suspend called from chrome and content side, we need to create new methods. Differential Revision: https://phabricator.services.mozilla.com/D16612
dom/base/nsGlobalWindowInner.cpp
dom/media/webaudio/AudioContext.cpp
dom/media/webaudio/AudioContext.h
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -5396,18 +5396,17 @@ void nsGlobalWindowInner::Suspend() {
   }
 
   SuspendIdleRequests();
 
   mTimeoutManager->Suspend();
 
   // Suspend all of the AudioContexts for this window
   for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
-    ErrorResult dummy;
-    RefPtr<Promise> d = mAudioContexts[i]->Suspend(dummy);
+    mAudioContexts[i]->SuspendFromChrome();
   }
 }
 
 void nsGlobalWindowInner::Resume() {
   MOZ_ASSERT(NS_IsMainThread());
 
   // We can only safely resume a window if its the current inner window.  If
   // its not the current inner, then we are in one of two different cases.
@@ -5438,18 +5437,17 @@ void nsGlobalWindowInner::Resume() {
     for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
       ac->AddWindowListener(mEnabledSensors[i], this);
   }
   EnableGamepadUpdates();
   EnableVRUpdates();
 
   // Resume all of the AudioContexts for this window
   for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
-    ErrorResult dummy;
-    RefPtr<Promise> d = mAudioContexts[i]->Resume(dummy);
+    mAudioContexts[i]->ResumeFromChrome();
   }
 
   mTimeoutManager->Resume();
 
   ResumeIdleRequests();
 
   // Resume all of the workers for this window.  We must do this
   // after timeouts since workers may have queued events that can trigger
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -902,16 +902,25 @@ already_AddRefed<Promise> AudioContext::
     return promise.forget();
   }
 
   mPromiseGripArray.AppendElement(promise);
   SuspendInternal(promise);
   return promise.forget();
 }
 
+void AudioContext::SuspendFromChrome() {
+  // Not support suspend call for these situations.
+  if (mAudioContextState == AudioContextState::Suspended || mIsOffline ||
+      (mAudioContextState == AudioContextState::Closed || mCloseCalled)) {
+    return;
+  }
+  SuspendInternal(nullptr);
+}
+
 void AudioContext::SuspendInternal(void* aPromise) {
   Destination()->Suspend();
 
   nsTArray<MediaStream*> streams;
   // If mSuspendCalled is true then we already suspended all our streams,
   // so don't suspend them again (since suspend(); suspend(); resume(); should
   // cancel both suspends). But we still need to do ApplyAudioContextOperation
   // to ensure our new promise is resolved.
@@ -919,16 +928,25 @@ void AudioContext::SuspendInternal(void*
     streams = GetAllStreams();
   }
   Graph()->ApplyAudioContextOperation(DestinationStream(), streams,
                                       AudioContextOperation::Suspend, aPromise);
 
   mSuspendCalled = true;
 }
 
+void AudioContext::ResumeFromChrome() {
+  // Not support resume call for these situations.
+  if (mAudioContextState == AudioContextState::Running || mIsOffline ||
+      (mAudioContextState == AudioContextState::Closed || mCloseCalled)) {
+    return;
+  }
+  ResumeInternal();
+}
+
 already_AddRefed<Promise> AudioContext::Resume(ErrorResult& aRv) {
   nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject());
   RefPtr<Promise> promise;
   promise = Promise::Create(parentObject, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
--- a/dom/media/webaudio/AudioContext.h
+++ b/dom/media/webaudio/AudioContext.h
@@ -196,16 +196,22 @@ class AudioContext final : public DOMEve
   // When back on the main thread, we can resolve or reject the promise, by
   // casting it back to a `Promise*` while asserting we're back on the main
   // thread and removing the reference we added.
   already_AddRefed<Promise> Suspend(ErrorResult& aRv);
   already_AddRefed<Promise> Resume(ErrorResult& aRv);
   already_AddRefed<Promise> Close(ErrorResult& aRv);
   IMPL_EVENT_HANDLER(statechange)
 
+  // These two functions are similar with Suspend() and Resume(), the difference
+  // is they are designed for calling from chrome side, not content side. eg.
+  // calling from inner window, so we won't need to return promise for caller.
+  void SuspendFromChrome();
+  void ResumeFromChrome();
+
   already_AddRefed<AudioBufferSourceNode> CreateBufferSource(ErrorResult& aRv);
 
   already_AddRefed<ConstantSourceNode> CreateConstantSource(ErrorResult& aRv);
 
   already_AddRefed<AudioBuffer> CreateBuffer(uint32_t aNumberOfChannels,
                                              uint32_t aLength,
                                              float aSampleRate,
                                              ErrorResult& aRv);