Bug 1517324 - part2: add autoplay test for createMediaStreamSource() with active stream r=karlt
authorAlastor Wu <alwu@mozilla.com>
Wed, 06 Feb 2019 23:07:02 +0000
changeset 457647 0f80b6c7fb66f1d1e7c048ca038440328ec632a7
parent 457646 a04946ac4b3cdcd957b6636dd0212c96c6362e18
child 457648 0cf7c3cc360e4fea4b611e9dbb3aa65572bed371
push id35516
push userrmaries@mozilla.com
push dateFri, 08 Feb 2019 04:23:26 +0000
treeherdermozilla-central@d599d1a73a3a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs1517324
milestone67.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 1517324 - part2: add autoplay test for createMediaStreamSource() with active stream r=karlt Differential Revision: https://phabricator.services.mozilla.com/D18577
dom/media/test/mochitest.ini
dom/media/test/test_autoplay_policy_web_audio_createMediaStreamSource.html
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -725,16 +725,18 @@ skip-if = android_version >= '23' # bug 
 [test_autoplay_policy_permission.html]
 skip-if = android_version >= '23' # bug 1424903
 [test_autoplay_policy_web_audio_notResumePageInvokedSuspendedAudioContext.html]
 skip-if = android_version >= '23' # bug 1424903
 [test_autoplay_policy_web_audio_mediaElementAudioSourceNode.html]
 skip-if = android_version >= '23' # bug 1424903
 [test_autoplay_policy_web_audio_AudioParamStream.html]
 skip-if = android_version >= '23' # bug 1424903
+[test_autoplay_policy_web_audio_createMediaStreamSource.html]
+skip-if = android_version >= '23' # bug 1424903
 [test_buffered.html]
 skip-if = android_version == '22' # bug 1308388, android(bug 1232305)
 [test_bug448534.html]
 [test_bug463162.xhtml]
 [test_bug465498.html]
 skip-if = toolkit == 'android' # android(bug 1232305)
 [test_bug495145.html]
 skip-if = toolkit == 'android' # android(bug 1232305)
new file mode 100644
--- /dev/null
+++ b/dom/media/test/test_autoplay_policy_web_audio_createMediaStreamSource.html
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Autoplay policy test : createMediaStreamSource with active stream</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<script>
+
+/**
+ * This test is used to ensure that we would try to start the blocked AudioContext
+ * which is blocked by autoplay policy, when it creates a MediaStreamAudioSourceNode
+ * which has a active input stream.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+(async function testStartAudioContextWhenCreatingMediaStreamAudioSourceWithActiveStream() {
+  await setupTestPreferences();
+
+  info(`- create 2 AudioContext, one is used to generate active stream, another one is used to test whether it would be resumed after starting MediaStreamAudioSource with active stream -`);
+  createAudioContexts();
+
+  info(`- both AudioContext are not allowed to start in beginning -`);
+  await audioContextsShouldBeBlocked();
+
+  info(`- using AudioContext2 to create a MediaStreamAudioSourceNode with active stream, which should resume AudioContext2 -`);
+  await createMediaStreamAudioSourceByAudioContext2();
+
+  endTest();
+})();
+
+/**
+ * Test utility functions
+ */
+
+function setupTestPreferences() {
+  return SpecialPowers.pushPrefEnv({"set": [
+    ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
+    ["media.autoplay.enabled.user-gestures-needed", true],
+    ["media.autoplay.block-webaudio", true],
+    ["media.autoplay.block-event.enabled", true],
+  ]});
+}
+
+function createAudioContexts() {
+  window.ac1 = new AudioContext();
+  window.ac2 = new AudioContext();
+
+  ac1.allowedToStart = new Promise(resolve => {
+    ac1.addEventListener("statechange", function() {
+      if (ac1.state === "running") {
+        resolve();
+      }
+    }, {once: true});
+  });
+
+  ac1.notAllowedToStart = new Promise(resolve => {
+    ac1.addEventListener("blocked", async function() {
+      resolve();
+    }, {once: true});
+  });
+
+
+  ac2.allowedToStart = new Promise(resolve => {
+    ac2.addEventListener("statechange", function() {
+      if (ac2.state === "running") {
+        resolve();
+      }
+    }, {once: true});
+  });
+
+  ac2.notAllowedToStart = new Promise(resolve => {
+    ac2.addEventListener("blocked", async function() {
+      resolve();
+    }, {once: true});
+  });
+}
+
+async function audioContextsShouldBeBlocked() {
+  await ac1.notAllowedToStart;
+  await ac2.notAllowedToStart;
+  is(ac1.state, "suspended", `AudioContext1 is blocked.`);
+  is(ac2.state, "suspended", `AudioContext2 is blocked.`);
+}
+
+async function startAudioContext1() {
+  // simulate user gesture in order to start video.
+  SpecialPowers.wrap(document).notifyUserGestureActivation();
+  ok(await ac1.resume().then(() => true, () => false), `resumed AudioContext1.`);
+  await ac1.allowedToStart;
+  is(ac1.state, "running", `AudioContext1 is running.`);
+}
+
+async function getActiveStream() {
+  await startAudioContext1();
+  // As AudioContext1 has been resumed, we can use it to create active stream.
+  return ac1.createMediaStreamDestination().stream;
+}
+
+async function createMediaStreamAudioSourceByAudioContext2() {
+  is(ac2.state, "suspended", `AudioContext2 is suspended.`);
+  let source = ac2.createMediaStreamSource(await getActiveStream());
+  source.connect(ac2.destination);
+  await ac2.allowedToStart;
+  is(ac2.state, "running", `AudioContext2 is running.`);
+}
+
+function endTest() {
+  // reset the activation flag in order not to interfere following test in the
+  // verify mode which would run the test using same document couple times.
+  SpecialPowers.wrap(document).clearUserGestureActivation();
+  SimpleTest.finish();
+}
+
+</script>