tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

head.js (5033B)


      1 "use strict";
      2 
      3 const DEFAULT_AUDIO_SAMPLE_FILE = "hello.ogg";
      4 const SPEECH_RECOGNITION_TEST_REQUEST_EVENT_TOPIC =
      5  "SpeechRecognitionTest:RequestEvent";
      6 const SPEECH_RECOGNITION_TEST_END_TOPIC = "SpeechRecognitionTest:End";
      7 
      8 var errorCodes = {
      9  NO_SPEECH: "no-speech",
     10  ABORTED: "aborted",
     11  AUDIO_CAPTURE: "audio-capture",
     12  NETWORK: "network",
     13  NOT_ALLOWED: "not-allowed",
     14  SERVICE_NOT_ALLOWED: "service-not-allowed",
     15  BAD_GRAMMAR: "bad-grammar",
     16  LANGUAGE_NOT_SUPPORTED: "language-not-supported",
     17 };
     18 
     19 var Services = SpecialPowers.Services;
     20 
     21 function EventManager(sr) {
     22  var self = this;
     23  var nEventsExpected = 0;
     24  self.eventsReceived = [];
     25 
     26  var allEvents = [
     27    "audiostart",
     28    "soundstart",
     29    "speechstart",
     30    "speechend",
     31    "soundend",
     32    "audioend",
     33    "result",
     34    "nomatch",
     35    "error",
     36    "start",
     37    "end",
     38  ];
     39 
     40  var eventDependencies = {
     41    speechend: "speechstart",
     42    soundend: "soundstart",
     43    audioend: "audiostart",
     44  };
     45 
     46  var isDone = false;
     47 
     48  // set up grammar
     49  var sgl = new SpeechGrammarList();
     50  sgl.addFromString("#JSGF V1.0; grammar test; public <simple> = hello ;", 1);
     51  sr.grammars = sgl;
     52 
     53  // AUDIO_DATA events are asynchronous,
     54  // so we queue events requested while they are being
     55  // issued to make them seem synchronous
     56  var isSendingAudioData = false;
     57  var queuedEventRequests = [];
     58 
     59  // register default handlers
     60  for (var i = 0; i < allEvents.length; i++) {
     61    (function (eventName) {
     62      sr["on" + eventName] = function (evt) {
     63        var message = "unexpected event: " + eventName;
     64        if (eventName == "error") {
     65          message += " -- " + evt.message;
     66        }
     67 
     68        ok(false, message);
     69        if (self.doneFunc && !isDone) {
     70          isDone = true;
     71          self.doneFunc();
     72        }
     73      };
     74    })(allEvents[i]);
     75  }
     76 
     77  self.expect = function EventManager_expect(eventName, cb) {
     78    nEventsExpected++;
     79 
     80    sr["on" + eventName] = function (evt) {
     81      self.eventsReceived.push(eventName);
     82      ok(true, "received event " + eventName);
     83 
     84      var dep = eventDependencies[eventName];
     85      if (dep) {
     86        ok(
     87          self.eventsReceived.includes(dep),
     88          eventName + " must come after " + dep
     89        );
     90      }
     91 
     92      cb && cb(evt, sr);
     93      if (
     94        self.doneFunc &&
     95        !isDone &&
     96        nEventsExpected === self.eventsReceived.length
     97      ) {
     98        isDone = true;
     99        self.doneFunc();
    100      }
    101    };
    102  };
    103 
    104  self.start = function EventManager_start() {
    105    isSendingAudioData = true;
    106    var audioTag = document.createElement("audio");
    107    audioTag.src = self.audioSampleFile;
    108 
    109    var stream = audioTag.mozCaptureStreamUntilEnded();
    110    audioTag.addEventListener("ended", function () {
    111      info("Sample stream ended, requesting queued events");
    112      isSendingAudioData = false;
    113      while (queuedEventRequests.length) {
    114        self.requestFSMEvent(queuedEventRequests.shift());
    115      }
    116    });
    117 
    118    audioTag.play();
    119    sr.start(stream);
    120  };
    121 
    122  self.requestFSMEvent = function EventManager_requestFSMEvent(eventName) {
    123    if (isSendingAudioData) {
    124      info(
    125        "Queuing event " + eventName + " until we're done sending audio data"
    126      );
    127      queuedEventRequests.push(eventName);
    128      return;
    129    }
    130 
    131    info("requesting " + eventName);
    132    Services.obs.notifyObservers(
    133      null,
    134      SPEECH_RECOGNITION_TEST_REQUEST_EVENT_TOPIC,
    135      eventName
    136    );
    137  };
    138 
    139  self.requestTestEnd = function EventManager_requestTestEnd() {
    140    Services.obs.notifyObservers(null, SPEECH_RECOGNITION_TEST_END_TOPIC);
    141  };
    142 }
    143 
    144 function buildResultCallback(transcript) {
    145  return function (evt) {
    146    is(evt.results[0][0].transcript, transcript, "expect correct transcript");
    147  };
    148 }
    149 
    150 function buildErrorCallback(errcode) {
    151  return function (err) {
    152    is(err.error, errcode, "expect correct error code");
    153  };
    154 }
    155 
    156 function performTest(options) {
    157  var prefs = options.prefs;
    158 
    159  prefs.unshift(
    160    ["media.webspeech.recognition.enable", true],
    161    ["media.webspeech.test.enable", true]
    162  );
    163 
    164  SpecialPowers.pushPrefEnv({ set: prefs }, function () {
    165    var sr;
    166    if (!options.webkit) {
    167      sr = new SpeechRecognition();
    168    } else {
    169      sr = new webkitSpeechRecognition();
    170      var grammar = new webkitSpeechGrammar();
    171      var speechrecognitionlist = new webkitSpeechGrammarList();
    172      speechrecognitionlist.addFromString("", 1);
    173      sr.grammars = speechrecognitionlist;
    174    }
    175    var em = new EventManager(sr);
    176 
    177    for (var eventName in options.expectedEvents) {
    178      var cb = options.expectedEvents[eventName];
    179      em.expect(eventName, cb);
    180    }
    181 
    182    em.doneFunc = function () {
    183      em.requestTestEnd();
    184      if (options.doneFunc) {
    185        options.doneFunc();
    186      }
    187    };
    188 
    189    em.audioSampleFile = DEFAULT_AUDIO_SAMPLE_FILE;
    190    if (options.audioSampleFile) {
    191      em.audioSampleFile = options.audioSampleFile;
    192    }
    193 
    194    em.start();
    195 
    196    for (var i = 0; i < options.eventsToRequest.length; i++) {
    197      em.requestFSMEvent(options.eventsToRequest[i]);
    198    }
    199  });
    200 }