content/media/webspeech/synth/test/common.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 var gSpeechRegistry = SpecialPowers.Cc["@mozilla.org/synth-voice-registry;1"]
michael@0 2 .getService(SpecialPowers.Ci.nsISynthVoiceRegistry);
michael@0 3
michael@0 4 var gAddedVoices = [];
michael@0 5
michael@0 6 function SpeechTaskCallback(onpause, onresume, oncancel) {
michael@0 7 this.onpause = onpause;
michael@0 8 this.onresume = onresume;
michael@0 9 this.oncancel = oncancel;
michael@0 10 }
michael@0 11
michael@0 12 SpeechTaskCallback.prototype = {
michael@0 13 QueryInterface: function(iid) {
michael@0 14 return this;
michael@0 15 },
michael@0 16
michael@0 17 getInterfaces: function(c) {},
michael@0 18
michael@0 19 getHelperForLanguage: function() {},
michael@0 20
michael@0 21 onPause: function onPause() {
michael@0 22 if (this.onpause)
michael@0 23 this.onpause();
michael@0 24 },
michael@0 25
michael@0 26 onResume: function onResume() {
michael@0 27 if (this.onresume)
michael@0 28 this.onresume();
michael@0 29 },
michael@0 30
michael@0 31 onCancel: function onCancel() {
michael@0 32 if (this.oncancel)
michael@0 33 this.oncancel();
michael@0 34 }
michael@0 35 };
michael@0 36
michael@0 37 var TestSpeechServiceWithAudio = SpecialPowers.wrapCallbackObject({
michael@0 38 CHANNELS: 1,
michael@0 39 SAMPLE_RATE: 16000,
michael@0 40
michael@0 41 serviceType: SpecialPowers.Ci.nsISpeechService.SERVICETYPE_DIRECT_AUDIO,
michael@0 42
michael@0 43 speak: function speak(aText, aUri, aRate, aPitch, aTask) {
michael@0 44 var task = SpecialPowers.wrap(aTask);
michael@0 45
michael@0 46 window.setTimeout(
michael@0 47 function () {
michael@0 48 task.setup(SpecialPowers.wrapCallbackObject(new SpeechTaskCallback()), this.CHANNELS, this.SAMPLE_RATE);
michael@0 49 // 0.025 seconds per character.
michael@0 50 task.sendAudio(new Int16Array((this.SAMPLE_RATE/40)*aText.length), []);
michael@0 51 task.sendAudio(new Int16Array(0), []);
michael@0 52 }.bind(this), 0);
michael@0 53 },
michael@0 54
michael@0 55 QueryInterface: function(iid) {
michael@0 56 return this;
michael@0 57 },
michael@0 58
michael@0 59 getInterfaces: function(c) {},
michael@0 60
michael@0 61 getHelperForLanguage: function() {}
michael@0 62 });
michael@0 63
michael@0 64 var TestSpeechServiceNoAudio = SpecialPowers.wrapCallbackObject({
michael@0 65 serviceType: SpecialPowers.Ci.nsISpeechService.SERVICETYPE_INDIRECT_AUDIO,
michael@0 66
michael@0 67 speak: function speak(aText, aUri, aRate, aPitch, aTask) {
michael@0 68 var pair = this.expectedSpeaks.shift();
michael@0 69 if (pair) {
michael@0 70 // XXX: These tests do not happen in OOP
michael@0 71 var utterance = pair[0];
michael@0 72 var expected = pair[1];
michael@0 73
michael@0 74 is(aText, utterance.text, "Speak text matches utterance text");
michael@0 75
michael@0 76 var args = {uri: aUri, rate: aRate, pitch: aPitch};
michael@0 77
michael@0 78 for (var attr in args) {
michael@0 79 if (expected[attr] != undefined)
michael@0 80 is(args[attr], expected[attr], "expected service arg " + attr);
michael@0 81 }
michael@0 82 }
michael@0 83
michael@0 84 var task = SpecialPowers.wrap(aTask);
michael@0 85 task.setup(SpecialPowers.wrapCallbackObject(new SpeechTaskCallback()));
michael@0 86 setTimeout(function () {
michael@0 87 task.dispatchStart();
michael@0 88 setTimeout(function () {
michael@0 89 task.dispatchEnd(aText.length / 2.0, aText.length);
michael@0 90 }, 0);
michael@0 91
michael@0 92 }, 0);
michael@0 93 },
michael@0 94
michael@0 95 QueryInterface: function(iid) {
michael@0 96 return this;
michael@0 97 },
michael@0 98
michael@0 99 getInterfaces: function(c) {},
michael@0 100
michael@0 101 getHelperForLanguage: function() {},
michael@0 102
michael@0 103 expectedSpeaks: []
michael@0 104 });
michael@0 105
michael@0 106 function synthAddVoice(aServiceName, aName, aLang, aIsLocal) {
michael@0 107 if (SpecialPowers.isMainProcess()) {
michael@0 108 var voicesBefore = speechSynthesis.getVoices().length;
michael@0 109 var uri = "urn:moz-tts:mylittleservice:" + encodeURI(aName + '?' + aLang);
michael@0 110 gSpeechRegistry.addVoice(window[aServiceName], uri, aName, aLang, aIsLocal);
michael@0 111
michael@0 112 gAddedVoices.push([window[aServiceName], uri]);
michael@0 113 var voicesAfter = speechSynthesis.getVoices().length;
michael@0 114
michael@0 115 is(voicesBefore + 1, voicesAfter, "Voice added");
michael@0 116 var voice = speechSynthesis.getVoices()[voicesAfter - 1];
michael@0 117 is(voice.voiceURI, uri, "voice URI matches");
michael@0 118 is(voice.name, aName, "voice name matches");
michael@0 119 is(voice.lang, aLang, "voice lang matches");
michael@0 120 is(voice.localService, aIsLocal, "voice localService matches");
michael@0 121
michael@0 122 return uri;
michael@0 123 } else {
michael@0 124 // XXX: It would be nice to check here that the child gets the voice
michael@0 125 // added update, but alas, it is aynchronous.
michael@0 126 var mm = SpecialPowers.Cc["@mozilla.org/childprocessmessagemanager;1"]
michael@0 127 .getService(SpecialPowers.Ci.nsISyncMessageSender);
michael@0 128
michael@0 129 return mm.sendSyncMessage(
michael@0 130 'test:SpeechSynthesis:ipcSynthAddVoice',
michael@0 131 [aServiceName, aName, aLang, aIsLocal])[0];
michael@0 132 }
michael@0 133 }
michael@0 134
michael@0 135 function synthSetDefault(aUri, aIsDefault) {
michael@0 136 if (SpecialPowers.isMainProcess()) {
michael@0 137 gSpeechRegistry.setDefaultVoice(aUri, aIsDefault);
michael@0 138 var voices = speechSynthesis.getVoices();
michael@0 139 for (var i in voices) {
michael@0 140 if (voices[i].voiceURI == aUri)
michael@0 141 ok(voices[i]['default'], "Voice set to default");
michael@0 142 }
michael@0 143 } else {
michael@0 144 // XXX: It would be nice to check here that the child gets the voice
michael@0 145 // added update, but alas, it is aynchronous.
michael@0 146 var mm = SpecialPowers.Cc["@mozilla.org/childprocessmessagemanager;1"]
michael@0 147 .getService(SpecialPowers.Ci.nsISyncMessageSender);
michael@0 148
michael@0 149 return mm.sendSyncMessage(
michael@0 150 'test:SpeechSynthesis:ipcSynthSetDefault', [aUri, aIsDefault])[0];
michael@0 151 }
michael@0 152 }
michael@0 153
michael@0 154 function synthCleanup() {
michael@0 155 if (SpecialPowers.isMainProcess()) {
michael@0 156 var voicesBefore = speechSynthesis.getVoices().length;
michael@0 157 var toRemove = gAddedVoices.length;
michael@0 158 var removeArgs;
michael@0 159 while ((removeArgs = gAddedVoices.shift()))
michael@0 160 gSpeechRegistry.removeVoice.apply(gSpeechRegistry.removeVoice, removeArgs);
michael@0 161
michael@0 162 var voicesAfter = speechSynthesis.getVoices().length;
michael@0 163 is(voicesAfter, voicesBefore - toRemove, "Successfully removed test voices");
michael@0 164 } else {
michael@0 165 // XXX: It would be nice to check here that the child gets the voice
michael@0 166 // removed update, but alas, it is aynchronous.
michael@0 167 var mm = SpecialPowers.Cc["@mozilla.org/childprocessmessagemanager;1"]
michael@0 168 .getService(SpecialPowers.Ci.nsISyncMessageSender);
michael@0 169 mm.sendSyncMessage('test:SpeechSynthesis:ipcSynthCleanup');
michael@0 170 }
michael@0 171 }
michael@0 172
michael@0 173 function synthTestQueue(aTestArgs, aEndFunc) {
michael@0 174 var utterances = [];
michael@0 175 for (var i in aTestArgs) {
michael@0 176 var uargs = aTestArgs[i][0];
michael@0 177 var u = new SpeechSynthesisUtterance(uargs.text);
michael@0 178
michael@0 179 delete uargs.text;
michael@0 180
michael@0 181 for (var attr in uargs)
michael@0 182 u[attr] = uargs[attr];
michael@0 183
michael@0 184 function onend_handler(e) {
michael@0 185 is(e.target, utterances.shift(), "Target matches utterances");
michael@0 186 ok(!speechSynthesis.speaking, "speechSynthesis is not speaking.");
michael@0 187
michael@0 188 isnot(e.eventType, 'error', "Error in utterance");
michael@0 189
michael@0 190 if (utterances.length) {
michael@0 191 ok(speechSynthesis.pending, "other utterances queued");
michael@0 192 } else {
michael@0 193 ok(!speechSynthesis.pending, "queue is empty, nothing pending.");
michael@0 194 if (aEndFunc)
michael@0 195 aEndFunc();
michael@0 196 }
michael@0 197 }
michael@0 198
michael@0 199 u.addEventListener('end', onend_handler);
michael@0 200 u.addEventListener('error', onend_handler);
michael@0 201
michael@0 202 u.addEventListener(
michael@0 203 'error', function onerror_handler(e) {
michael@0 204 ok(false, "Error in speech utterance '" + e.target.text + "'");
michael@0 205 });
michael@0 206
michael@0 207 utterances.push(u);
michael@0 208 TestSpeechServiceNoAudio.expectedSpeaks.push([u, aTestArgs[i][1]]);
michael@0 209 speechSynthesis.speak(u);
michael@0 210 }
michael@0 211
michael@0 212 ok(!speechSynthesis.speaking, "speechSynthesis is not speaking yet.");
michael@0 213 ok(speechSynthesis.pending, "speechSynthesis has an utterance queued.");
michael@0 214 }

mercurial