Bug 999350 - Change initial values of AudioChannelService::mCurrentHigherChannel and mCurrentVisibleHigherChannel to -1 and add test case for audio-channel-change & visible-audio-channel-change of mozChromeEvent. r=baku
authorMarco Chen <mchen@mozilla.com>
Fri, 25 Apr 2014 18:22:17 +0800
changeset 180655 d3aaf927afb895ad0efffa5c41ba4e1219e93c53
parent 180654 8d160a730493b05033dea84c7583ae697d9f2ed6
child 180656 7c7c5f144eb2f615963c3188f64460c3472174de
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersbaku
bugs999350
milestone31.0a1
Bug 999350 - Change initial values of AudioChannelService::mCurrentHigherChannel and mCurrentVisibleHigherChannel to -1 and add test case for audio-channel-change & visible-audio-channel-change of mozChromeEvent. r=baku
dom/audiochannel/AudioChannelService.cpp
dom/audiochannel/tests/AudioChannelChromeScript.js
dom/audiochannel/tests/file_audio.html
dom/audiochannel/tests/mochitest.ini
dom/audiochannel/tests/moz.build
dom/audiochannel/tests/test_audioChannelChange.html
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -82,18 +82,18 @@ AudioChannelService::Shutdown()
   if (gAudioChannelService) {
     gAudioChannelService = nullptr;
   }
 }
 
 NS_IMPL_ISUPPORTS2(AudioChannelService, nsIObserver, nsITimerCallback)
 
 AudioChannelService::AudioChannelService()
-: mCurrentHigherChannel(INT32_MAX)
-, mCurrentVisibleHigherChannel(INT32_MAX)
+: mCurrentHigherChannel(-1)
+, mCurrentVisibleHigherChannel(-1)
 , mPlayableHiddenContentChildID(CONTENT_PROCESS_ID_UNKNOWN)
 , mDisabled(false)
 , mDefChannelChildID(CONTENT_PROCESS_ID_UNKNOWN)
 {
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->AddObserver(this, "ipc:content-shutdown", false);
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/AudioChannelChromeScript.js
@@ -0,0 +1,18 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+const { Services } = Cu.import('resource://gre/modules/Services.jsm');
+const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
+
+addMessageListener('init-chrome-event', function(message) {
+  // listen mozChromeEvent and forward to content process.
+  let type = message.type;
+
+  SystemAppProxy.addEventListener('mozChromeEvent', function(event) {
+    let details = event.detail;
+    if (details.type === type) {
+      sendAsyncMessage('chrome-event', details);
+    }
+  }, true);
+});
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/file_audio.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test audio-channel-changed & visible-audio-channel-changed mozChromeEvent</title>
+</head>
+<body>
+  <div id="content"></div>
+  <script>
+  var normalAudio;
+  var contentAudio;
+  var notificationAudio;
+  var alarmAudio;
+  var telephonyAudio;
+  var ringerAudio;
+  var publicnotificationAudio;
+
+  function playWithAudioType(audio, type) {
+    audio.mozAudioChannelType = type;
+    audio.src = "test.ogg";
+    audio.loop = true;
+
+    audio.play();
+  }
+
+  function runTest() {
+    // normal channel.
+    normalAudio = new Audio();
+    playWithAudioType(normalAudio, 'normal');
+
+    // content channel.
+    contentAudio = new Audio();
+    playWithAudioType(contentAudio, 'content');
+
+    // notification channel.
+    notificationAudio = new Audio();
+    playWithAudioType(notificationAudio, 'notification');
+
+    // alarm channel.
+    alarmAudio = new Audio();
+    playWithAudioType(alarmAudio, 'alarm');
+
+    // telephony channel.
+    telephonyAudio = new Audio();
+    playWithAudioType(telephonyAudio, 'telephony');
+
+    // ringer channel.
+    ringerAudio = new Audio();
+    playWithAudioType(ringerAudio, 'ringer');
+
+    // publicnotification channel.
+    publicnotificationAudio = new Audio();
+    playWithAudioType(publicnotificationAudio, 'publicnotification');
+
+    window.addEventListener('hashchange', function(event) {
+      if (location.hash == "#pauseAudio") {
+        publicnotificationAudio.pause();
+        ringerAudio.pause();
+        telephonyAudio.pause();
+      }
+
+      if (location.hash == "#pauseAudioFollowing") {
+        alarmAudio.pause();
+        notificationAudio.pause();
+        contentAudio.pause();
+        normalAudio.pause();
+      }
+    }, false);
+  }
+
+  function checkBackgroundStatus() {
+    if (location.hash == "#fg") {
+      runTest();
+      return;
+    }
+
+    if (document.hidden) {
+      runTest();
+      return;
+    }
+
+    document.addEventListener('visibilitychange', function visibilityChange() {
+      if (document.hidden) {
+        runTest();
+      }
+    });
+  }
+
+  SpecialPowers.pushPermissions(
+    [{ "type": "audio-channel-content", "allow": 1, "context": document },
+     { "type": "audio-channel-notification", "allow": 1, "context": document },
+     { "type": "audio-channel-alarm", "allow": 1, "context": document },
+     { "type": "audio-channel-telephony", "allow": 1, "context": document },
+     { "type": "audio-channel-ringer", "allow": 1, "context": document },
+     { "type": "audio-channel-publicnotification", "allow": 1, "context": document }],
+    checkBackgroundStatus);
+
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/mochitest.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+support-files =
+  file_audio.html
+  AudioChannelChromeScript.js
+
+[test_audioChannelChange.html]
+skip-if = (toolkit != 'gonk')
--- a/dom/audiochannel/tests/moz.build
+++ b/dom/audiochannel/tests/moz.build
@@ -6,10 +6,12 @@
 
 CPP_UNIT_TESTS += [
     'TestAudioChannelService.cpp',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     DEFINES['NOMINMAX'] = True
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
 FAIL_ON_WARNINGS = True
 
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/test_audioChannelChange.html
@@ -0,0 +1,209 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test audio-channel-changed & visible-audio-channel-changed mozChromeEvent</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+  <div id="content"></div>
+  <script type="application/javascript;version=1.7">
+  var expectedAudioTypes;
+  var expectedVisibleAudioTypes;
+  var expectedVisibleAudioType;
+  var index;
+  var visibleIndex;
+  var iframe1;
+  var normalAudio;
+
+  function playWithAudioType(audio, type) {
+    audio.mozAudioChannelType = type;
+    audio.src = "test.ogg";
+    audio.loop = true;
+
+    audio.play();
+  }
+
+  function fgBgTestListener(message) {
+    var type = message.type;
+    var channel = message.channel;
+
+    if (type == 'audio-channel-changed') {
+      is(channel, expectedAudioTypes[index], channel + " is received and expected " + expectedAudioTypes[index]);
+      index++;
+    }
+
+    if (type == 'visible-audio-channel-changed') {
+      is(channel, expectedVisibleAudioType, channel + " is received and expected " + expectedVisibleAudioType);
+    }
+
+    // All audio types are playing now so ask to pause them.
+    // This call will stop audio from highest to telephony.
+    if ('cmd-pause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudio';
+      index++;
+    }
+
+    // According to there is a 1.5 second delay of releasing telephony,
+    // we need to wait for it then continue to pause others.
+    if ('cmd-secondPause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudioFollowing';
+      index++;
+    }
+
+    if (index == expectedAudioTypes.length) {
+      document.body.removeChild(iframe1);
+      script.removeMessageListener('chrome-event', fgBgTestListener);
+      normalAudio.pause();
+      SimpleTest.finish();
+    }
+  }
+
+  // Channel of visible-audio-channel-changed event should be always normal.
+  // Audios in background should not effect visible-audio-channel-changed.
+  function runFgBgTest() {
+    expectedAudioTypes = ["normal", "content", "notification",
+                          "alarm", "telephony", "ringer", "publicnotification", "cmd-pause",
+                          "ringer", "telephony", "alarm", "cmd-secondPause", "notification",
+                          "content", "normal"];
+    expectedVisibleAudioType = "normal";
+    index = 0;
+
+    script.addMessageListener('chrome-event', fgBgTestListener);
+
+    // To play a audio with normal channel in the foreground.
+    normalAudio = new Audio();
+    playWithAudioType(normalAudio, 'normal');
+
+    iframe1.src = 'file_audio.html#bg';
+    document.body.appendChild(iframe1);
+    iframe1.setVisible(false);
+  }
+
+  function bgTestListener(message) {
+    var type = message.type;
+    var channel = message.channel;
+
+    if (type == 'audio-channel-changed') {
+      is(channel, expectedAudioTypes[index], channel + " is received and expected " + expectedAudioTypes[index]);
+      index++;
+    }
+
+    if (type == 'visible-audio-channel-changed') {
+      is(channel, expectedVisibleAudioType, channel + " is received and expected " + expectedVisibleAudioType);
+    }
+
+    // All audio types are playing now so ask to pause them.
+    if ('cmd-pause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudio';
+      index++;
+    }
+
+    if ('cmd-secondPause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudioFollowing';
+      index++;
+    }
+
+    if (index == expectedAudioTypes.length) {
+      document.body.removeChild(iframe1);
+      script.removeMessageListener('chrome-event', bgTestListener);
+      runFgBgTest();
+    }
+  }
+
+  // 1. Channel of visible-audio-channel-changed event should be always none.
+  // 2. normal is not allowed to be played in the background.
+  function runBgTest() {
+    expectedAudioTypes = ["content", "notification",
+                          "alarm", "telephony", "ringer", "publicnotification", "cmd-pause",
+                         "ringer", "telephony", "alarm", "cmd-secondPause", "notification",
+                          "content", "none"];
+    expectedVisibleAudioType = "none";
+    index = 0;
+
+    script.addMessageListener('chrome-event', bgTestListener);
+
+    iframe1.src = 'file_audio.html#bg';
+    document.body.appendChild(iframe1);
+    iframe1.setVisible(false);
+  }
+
+  function fgTestListener(message) {
+    var type = message.type;
+    var channel = message.channel;
+
+    if (type == 'audio-channel-changed') {
+      is(channel, expectedAudioTypes[index], channel + " is received and expected " + expectedAudioTypes[index]);
+      index++;
+    }
+
+    if (type == 'visible-audio-channel-changed') {
+      is(channel, expectedAudioTypes[visibleIndex], channel + " is received and expected " + expectedAudioTypes[visibleIndex]);
+      visibleIndex++;
+    }
+
+    // All audio types are playing now so ask to pause them.
+    if ('cmd-pause' == expectedAudioTypes[visibleIndex] &&
+        'cmd-pause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudio';
+      visibleIndex++;
+      index++;
+    }
+
+    if ('cmd-secondPause' == expectedAudioTypes[visibleIndex] &&
+        'cmd-secondPause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudioFollowing';
+      visibleIndex++;
+      index++;
+    }
+
+    if (index == expectedAudioTypes.length && visibleIndex == expectedAudioTypes.length) {
+      document.body.removeChild(iframe1);
+      script.removeMessageListener('chrome-event', fgTestListener);
+      runBgTest();
+    }
+  }
+
+  // The foreground audio will effect both of audio-channel-changed and
+  // visible-audio-channel-changed.
+  function runFgTest() {
+    expectedAudioTypes = ["normal", "content", "notification",
+                          "alarm", "telephony", "ringer", "publicnotification",
+                          "cmd-pause", "ringer", "telephony", "alarm",
+                          "cmd-secondPause", "notification", "content",
+                          "normal", "none"];
+
+    index = 0;
+    visibleIndex = 0;
+
+    script.addMessageListener('chrome-event', fgTestListener);
+
+    iframe1 = document.createElement('iframe');
+    iframe1.setAttribute('mozbrowser', true);
+    iframe1.src = 'file_audio.html#fg';
+    document.body.appendChild(iframe1);
+  }
+
+  var url = SimpleTest.getTestFileURL("AudioChannelChromeScript.js")
+  var script = SpecialPowers.loadChromeScript(url);
+  script.sendAsyncMessage("init-chrome-event", {
+    type: 'audio-channel-changed'
+  });
+  script.sendAsyncMessage("init-chrome-event", {
+    type: 'visible-audio-channel-changed'
+  });
+
+  SimpleTest.waitForExplicitFinish();
+
+  SpecialPowers.pushPermissions(
+    [{ "type": "browser", "allow": 1, "context": document },
+     { "type": "embed-apps", "allow": 1, "context": document },
+     { "type": "webapps-manage", "allow": 1, "context": document }], function() {
+    SpecialPowers.pushPrefEnv({"set": [["dom.ipc.browser_frames.oop_by_default", true],
+                                       ["media.useAudioChannelService", true],
+                                       ["dom.mozBrowserFramesEnabled", true]]}, runFgTest);
+  });
+  </script>
+</body>
+</html>