Bug 1339230 - part3 : add test. r=baku
authorAlastor Wu <alwu@mozilla.com>
Fri, 24 Feb 2017 17:17:09 +0800
changeset 373722 541cb234a772d4cf62379538530b9534e1d141cc
parent 373721 20809c1055e5fd52544fe30d0f89847fcbad1b04
child 373723 96e5f8480e1109599cc567e91c5241ac2f63a03f
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1339230
milestone54.0a1
Bug 1339230 - part3 : add test. r=baku MozReview-Commit-ID: FzcEwErGad3
dom/audiochannel/AudioChannelService.cpp
modules/libpref/init/all.js
toolkit/content/tests/browser/browser.ini
toolkit/content/tests/browser/browser_audioCompeting_onlyForActiveAgent.js
toolkit/content/tests/browser/file_multiplePlayingAudio.html
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -36,16 +36,17 @@ using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::hal;
 
 namespace {
 
 // If true, any new AudioChannelAgent will be muted when created.
 bool sAudioChannelMutedByDefault = false;
 bool sAudioChannelCompeting = false;
+bool sAudioChannelCompetingAllAgents = false;
 bool sXPCOMShuttingDown = false;
 
 class NotifyChannelActiveRunnable final : public Runnable
 {
 public:
   NotifyChannelActiveRunnable(uint64_t aWindowID, AudioChannel aAudioChannel,
                               bool aActive)
     : Runnable("NotifyChannelActiveRunnable")
@@ -166,17 +167,17 @@ IsEnableAudioCompetingForAllAgents()
   // helps user can focus on one media at the same time. However, we hope to
   // treat all media as the same in the mobile device. First reason is we have
   // media control on fennec and we just want to control one media at once time.
   // Second reason is to reduce the bandwidth, avoiding to play any non-audible
   // media in background which user doesn't notice about.
 #ifdef MOZ_WIDGET_ANDROID
   return true;
 #else
-  return false;
+  return sAudioChannelCompetingAllAgents;
 #endif
 }
 
 } // anonymous namespace
 
 StaticRefPtr<AudioChannelService> gAudioChannelService;
 
 // Mappings from 'mozaudiochannel' attribute strings to an enumeration.
@@ -294,16 +295,18 @@ AudioChannelService::AudioChannelService
       obs->AddObserver(this, "ipc:content-shutdown", false);
     }
   }
 
   Preferences::AddBoolVarCache(&sAudioChannelMutedByDefault,
                                "dom.audiochannel.mutedByDefault");
   Preferences::AddBoolVarCache(&sAudioChannelCompeting,
                                "dom.audiochannel.audioCompeting");
+  Preferences::AddBoolVarCache(&sAudioChannelCompetingAllAgents,
+                               "dom.audiochannel.audioCompeting.allAgents");
 }
 
 AudioChannelService::~AudioChannelService()
 {
 }
 
 void
 AudioChannelService::NotifyCreatedNewAgent(AudioChannelAgent* aAgent)
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5536,16 +5536,17 @@ pref("plugins.navigator_hide_disabled_fl
 
 // Disable browser frames by default
 pref("dom.mozBrowserFramesEnabled", false);
 
 // Is support for 'color-adjust' CSS property enabled?
 pref("layout.css.color-adjust.enabled", true);
 
 pref("dom.audiochannel.audioCompeting", false);
+pref("dom.audiochannel.audioCompeting.allAgents", false);
 
 // Default media volume
 pref("media.default_volume", "1.0");
 
 // Once bug 1276272 is resolved, we will trun this preference to default ON in
 // non-release channels.
 #ifdef RELEASE_OR_BETA
 pref("media.seekToNextFrame.enabled", false);
--- a/toolkit/content/tests/browser/browser.ini
+++ b/toolkit/content/tests/browser/browser.ini
@@ -3,16 +3,20 @@ support-files =
   head.js
   file_contentTitle.html
   audio.ogg
 
 [browser_audioCompeting.js]
 tags = audiochannel
 support-files =
   file_multipleAudio.html
+[browser_audioCompeting_onlyForActiveAgent.js]
+tags = audiochannel
+support-files =
+  file_multiplePlayingAudio.html
 [browser_autoscroll_disabled.js]
 [browser_block_autoplay_media.js]
 tags = audiochannel
 support-files =
   file_multipleAudio.html
 [browser_block_silentAudioTrack_media.js]
 tags = audiochannel
 support-files =
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/browser/browser_audioCompeting_onlyForActiveAgent.js
@@ -0,0 +1,176 @@
+const PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_multiplePlayingAudio.html";
+
+var SuspendedType = {
+  NONE_SUSPENDED             : 0,
+  SUSPENDED_PAUSE            : 1,
+  SUSPENDED_BLOCK            : 2,
+  SUSPENDED_PAUSE_DISPOSABLE : 3
+};
+
+function wait_for_event(browser, event) {
+  return BrowserTestUtils.waitForEvent(browser, event, false, (event) => {
+    is(event.originalTarget, browser, "Event must be dispatched to correct browser.");
+    return true;
+  });
+}
+
+function check_all_audio_suspended(suspendedType) {
+  var audio1 = content.document.getElementById("audio1");
+  var audio2 = content.document.getElementById("audio2");
+  if (!audio1 || !audio2) {
+    ok(false, "Can't get the audio element!");
+  }
+
+  is(audio1.computedSuspended, suspendedType,
+     "The suspeded state of audio1 is correct.");
+  is(audio2.computedSuspended, suspendedType,
+     "The suspeded state of audio2 is correct.");
+}
+
+function check_audio1_suspended(suspendedType) {
+  var audio1 = content.document.getElementById("audio1");
+  if (!audio1) {
+    ok(false, "Can't get the audio element!");
+  }
+
+  is(audio1.computedSuspended, suspendedType,
+     "The suspeded state of audio1 is correct.");
+}
+
+function check_audio2_suspended(suspendedType) {
+  var audio2 = content.document.getElementById("audio2");
+  if (!audio2) {
+    ok(false, "Can't get the audio element!");
+  }
+
+  is(audio2.computedSuspended, suspendedType,
+     "The suspeded state of audio2 is correct.");
+}
+
+function check_all_audio_pause_state(expectedPauseState) {
+  var audio1 = content.document.getElementById("audio1");
+  var audio2 = content.document.getElementById("audio2");
+  if (!audio1 | !audio2) {
+    ok(false, "Can't get the audio element!");
+  }
+
+  is(audio1.paused, expectedPauseState,
+    "The pause state of audio1 is correct.");
+  is(audio2.paused, expectedPauseState,
+    "The pause state of audio2 is correct.");
+}
+
+function check_audio1_pause_state(expectedPauseState) {
+  var audio1 = content.document.getElementById("audio1");
+  if (!audio1) {
+    ok(false, "Can't get the audio element!");
+  }
+
+  is(audio1.paused, expectedPauseState,
+    "The pause state of audio1 is correct.");
+}
+
+function check_audio2_pause_state(expectedPauseState) {
+  var audio2 = content.document.getElementById("audio2");
+  if (!audio2) {
+    ok(false, "Can't get the audio element!");
+  }
+
+  is(audio2.paused, expectedPauseState,
+    "The pause state of audio2 is correct.");
+}
+
+function play_audio1_from_page() {
+  var audio1 = content.document.getElementById("audio1");
+  if (!audio1) {
+    ok(false, "Can't get the audio element!");
+  }
+
+  is(audio1.paused, true, "Audio1 is paused.");
+  audio1.play();
+  return new Promise(resolve => {
+    audio1.onplay = function() {
+      audio1.onplay = null;
+      ok(true, "Audio1 started playing.");
+      resolve();
+    }
+  });
+}
+
+function stop_audio1_from_page() {
+  var audio1 = content.document.getElementById("audio1");
+  if (!audio1) {
+    ok(false, "Can't get the audio element!");
+  }
+
+  is(audio1.paused, false, "Audio1 is playing.");
+  audio1.pause();
+  return new Promise(resolve => {
+    audio1.onpause = function() {
+      audio1.onpause = null;
+      ok(true, "Audio1 stopped playing.");
+      resolve();
+    }
+  });
+}
+
+function* audio_competing_for_active_agent(url, browser) {
+  browser.loadURI(url);
+
+  info("- page should have playing audio -");
+  yield wait_for_event(browser, "DOMAudioPlaybackStarted");
+
+  info("- the default suspended state of all audio should be non-suspened -");
+  yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
+                                   check_all_audio_suspended);
+
+  info("- only pause playing audio in the page -");
+  browser.pauseMedia(true /* disposable */);
+
+  info("- page shouldn't have any playing audio -");
+  yield wait_for_event(browser, "DOMAudioPlaybackStopped");
+  yield ContentTask.spawn(browser, true /* expect for pause */,
+                                   check_all_audio_pause_state);
+  yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE_DISPOSABLE,
+                                   check_all_audio_suspended);
+
+  info("- resume audio1 from page -");
+  yield ContentTask.spawn(browser, null,
+                                   play_audio1_from_page);
+  yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
+                                   check_audio1_suspended);
+
+  info("- audio2 should still be suspended -");
+  yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE_DISPOSABLE,
+                                   check_audio2_suspended);
+  yield ContentTask.spawn(browser, true /* expect for pause */,
+                                   check_audio2_pause_state);
+
+  info("- stop audio1 from page -");
+  yield ContentTask.spawn(browser, null,
+                                   stop_audio1_from_page);
+  yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
+                                   check_audio1_suspended);
+
+  info("- audio2 should still be suspended -");
+  yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE_DISPOSABLE,
+                                   check_audio2_suspended);
+  yield ContentTask.spawn(browser, true /* expect for pause */,
+                                   check_audio2_pause_state);
+
+}
+
+add_task(function* setup_test_preference() {
+  yield SpecialPowers.pushPrefEnv({"set": [
+    ["media.useAudioChannelService.testing", true],
+    ["dom.audiochannel.audioCompeting", true],
+    ["dom.audiochannel.audioCompeting.allAgents", true]
+  ]});
+});
+
+add_task(function* test_suspended_pause_disposable() {
+  yield BrowserTestUtils.withNewTab({
+      gBrowser,
+      url: "about:blank"
+    }, audio_competing_for_active_agent.bind(this, PAGE));
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/browser/file_multiplePlayingAudio.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<head>
+  <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
+  <meta content="utf-8" http-equiv="encoding">
+</head>
+<body>
+<audio id="audio1" src="audio.ogg" controls></audio>
+<audio id="audio2" src="audio.ogg" controls></audio>
+<script type="text/javascript">
+
+// In linux debug on try server, sometimes the download process would fail, so
+// we can't activate the "auto-play" or playing after receving "oncanplay".
+// Therefore, we just call play here.
+var audio1 = document.getElementById("audio1");
+audio1.loop = true;
+audio1.play();
+
+var audio2 = document.getElementById("audio2");
+audio2.loop = true;
+audio2.play();
+
+</script>
+</body>