From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001
From: "Matt A. Tobin" <mattatobin@localhost.localdomain>
Date: Fri, 2 Feb 2018 04:16:08 -0500
Subject: Add m-esr52 at 52.6.0

---
 dom/media/tests/mochitest/blacksilence.js | 121 ++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)
 create mode 100644 dom/media/tests/mochitest/blacksilence.js

(limited to 'dom/media/tests/mochitest/blacksilence.js')

diff --git a/dom/media/tests/mochitest/blacksilence.js b/dom/media/tests/mochitest/blacksilence.js
new file mode 100644
index 000000000..cad3b5515
--- /dev/null
+++ b/dom/media/tests/mochitest/blacksilence.js
@@ -0,0 +1,121 @@
+(function(global) {
+  'use strict';
+
+  // an invertible check on the condition.
+  // if the constraint is applied, then the check is direct
+  // if not applied, then the result should be reversed
+  function check(constraintApplied, condition, message) {
+    var good = constraintApplied ? condition : !condition;
+    message = (constraintApplied ? 'with' : 'without') +
+      ' constraint: should ' + (constraintApplied ? '' : 'not ') +
+      message + ' = ' + (good ? 'OK' : 'waiting...');
+    info(message);
+    return good;
+  }
+
+  function mkElement(type) {
+    // This makes an unattached element.
+    // It's not rendered to save the cycles that costs on b2g emulator
+    // and it gets dropped (and GC'd) when the test is done.
+    var e = document.createElement(type);
+    e.width = 32;
+    e.height = 24;
+    document.getElementById('display').appendChild(e);
+    return e;
+  }
+
+  // Runs checkFunc until it reports success.
+  // This is kludgy, but you have to wait for media to start flowing, and it
+  // can't be any old media, it has to include real data, for which we have no
+  // reliable signals to use as a trigger.
+  function periodicCheck(checkFunc) {
+    var resolve;
+    var done = false;
+    // This returns a function so that we create 10 closures in the loop, not
+    // one; and so that the timers don't all start straight away
+    var waitAndCheck = counter => () => {
+      if (done) {
+        return Promise.resolve();
+      }
+      return new Promise(r => setTimeout(r, 200 << counter))
+        .then(() => {
+          if (checkFunc()) {
+            done = true;
+            resolve();
+          }
+        });
+    };
+
+    var chain = Promise.resolve();
+    for (var i = 0; i < 10; ++i) {
+      chain = chain.then(waitAndCheck(i));
+    }
+    return new Promise(r => resolve = r);
+  }
+
+  function isSilence(audioData) {
+    var silence = true;
+    for (var i = 0; i < audioData.length; ++i) {
+      if (audioData[i] !== 128) {
+        silence = false;
+      }
+    }
+    return silence;
+  }
+
+  function checkAudio(constraintApplied, stream) {
+    var audio = mkElement('audio');
+    audio.srcObject = stream;
+    audio.play();
+
+    var context = new AudioContext();
+    var source = context.createMediaStreamSource(stream);
+    var analyser = context.createAnalyser();
+    source.connect(analyser);
+    analyser.connect(context.destination);
+
+    return periodicCheck(() => {
+      var sampleCount = analyser.frequencyBinCount;
+      info('got some audio samples: ' + sampleCount);
+      var buffer = new Uint8Array(sampleCount);
+      analyser.getByteTimeDomainData(buffer);
+
+      var silent = check(constraintApplied, isSilence(buffer),
+                         'be silence for audio');
+      return sampleCount > 0 && silent;
+    }).then(() => {
+      source.disconnect();
+      analyser.disconnect();
+      audio.pause();
+      ok(true, 'audio is ' + (constraintApplied ? '' : 'not ') + 'silent');
+    });
+  }
+
+  function checkVideo(constraintApplied, stream) {
+    var video = mkElement('video');
+    video.srcObject = stream;
+    video.play();
+
+    return periodicCheck(() => {
+      try {
+        var canvas = mkElement('canvas');
+        var ctx = canvas.getContext('2d');
+        // Have to guard drawImage with the try as well, due to bug 879717. If
+        // we get an error, this round fails, but that failure is usually just
+        // transitory.
+        ctx.drawImage(video, 0, 0);
+        ctx.getImageData(0, 0, 1, 1);
+        return check(constraintApplied, false, 'throw on getImageData for video');
+      } catch (e) {
+        return check(constraintApplied, e.name === 'SecurityError',
+                     'get a security error: ' + e.name);
+      }
+    }).then(() => {
+      video.pause();
+      ok(true, 'video is ' + (constraintApplied ? '' : 'not ') + 'protected');
+    });
+  }
+
+  global.audioIsSilence = checkAudio;
+  global.videoIsBlack = checkVideo;
+}(this));
-- 
cgit v1.2.3