author | Eitan Isaacson <eitan@monotonous.org> |
Thu, 16 Apr 2015 10:36:47 -0700 | |
changeset 239629 | 9268463eb2be7637e3990a4d084401cb09a48475 |
parent 239628 | 1801788ab9b45a21ee91bae49ed757c59a530ba5 |
child 239630 | 6e469cebd8d7bd1b9a48476efb1e9548c53c1098 |
push id | 28606 |
push user | ryanvm@gmail.com |
push date | Fri, 17 Apr 2015 19:45:37 +0000 |
treeherder | mozilla-central@a55f9bdb2bf4 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | smaug |
bugs | 1155034 |
milestone | 40.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
|
--- a/dom/media/webspeech/synth/SpeechSynthesis.cpp +++ b/dom/media/webspeech/synth/SpeechSynthesis.cpp @@ -191,25 +191,25 @@ SpeechSynthesis::Cancel() mCurrentTask->Cancel(); } } void SpeechSynthesis::Pause() { - if (mCurrentTask) { + if (mCurrentTask && !Paused() && (Speaking() || Pending())) { mCurrentTask->Pause(); } } void SpeechSynthesis::Resume() { - if (mCurrentTask) { + if (mCurrentTask && Paused()) { mCurrentTask->Resume(); } } void SpeechSynthesis::OnEnd(const nsSpeechTask* aTask) { MOZ_ASSERT(mCurrentTask == aTask);
--- a/dom/media/webspeech/synth/nsISpeechService.idl +++ b/dom/media/webspeech/synth/nsISpeechService.idl @@ -73,25 +73,25 @@ interface nsISpeechTask : nsISupports * Dispatch end event. * * @param aElapsedTime time in seconds since speech has started. * @param aCharIndex offset of spoken characters. */ void dispatchEnd(in float aElapsedTime, in unsigned long aCharIndex); /** - * Dispatch pause event. Should not be called directly by service. + * Dispatch pause event. * * @param aElapsedTime time in seconds since speech has started. * @param aCharIndex offset of spoken characters. */ void dispatchPause(in float aElapsedTime, in unsigned long aCharIndex); /** - * Dispatch resume event. Should not be called directly by service. + * Dispatch resume event. * * @param aElapsedTime time in seconds since speech has started. * @param aCharIndex offset of spoken characters. */ void dispatchResume(in float aElapsedTime, in unsigned long aCharIndex); /** * Dispatch error event.
--- a/dom/media/webspeech/synth/nsSpeechTask.cpp +++ b/dom/media/webspeech/synth/nsSpeechTask.cpp @@ -469,71 +469,59 @@ nsSpeechTask::DispatchMarkImpl(const nsA return NS_OK; } void nsSpeechTask::Pause() { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default); - if (mUtterance->IsPaused() || - mUtterance->GetState() == SpeechSynthesisUtterance::STATE_ENDED) { - return; - } - if (mCallback) { DebugOnly<nsresult> rv = mCallback->OnPause(); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to call onPause() callback"); } if (mStream) { mStream->ChangeExplicitBlockerCount(1); + DispatchPauseImpl(GetCurrentTime(), GetCurrentCharOffset()); } - - DispatchPauseImpl(GetCurrentTime(), GetCurrentCharOffset()); } void nsSpeechTask::Resume() { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default); - if (!mUtterance->IsPaused()) { - return; - } - if (mCallback) { DebugOnly<nsresult> rv = mCallback->OnResume(); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to call onResume() callback"); } if (mStream) { mStream->ChangeExplicitBlockerCount(-1); + DispatchResumeImpl(GetCurrentTime(), GetCurrentCharOffset()); } - - DispatchResumeImpl(GetCurrentTime(), GetCurrentCharOffset()); } void nsSpeechTask::Cancel() { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default); LOG(PR_LOG_DEBUG, ("nsSpeechTask::Cancel")); if (mCallback) { DebugOnly<nsresult> rv = mCallback->OnCancel(); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to call onCancel() callback"); } if (mStream) { mStream->ChangeExplicitBlockerCount(1); + DispatchEndImpl(GetCurrentTime(), GetCurrentCharOffset()); } - - DispatchEndImpl(GetCurrentTime(), GetCurrentCharOffset()); } float nsSpeechTask::GetCurrentTime() { return mStream ? (float)(mStream->GetCurrentTime() / 1000000.0) : 0; }
--- a/dom/media/webspeech/synth/test/common.js +++ b/dom/media/webspeech/synth/test/common.js @@ -76,24 +76,48 @@ var TestSpeechServiceNoAudio = SpecialPo var args = {uri: aUri, rate: aRate, pitch: aPitch}; for (var attr in args) { if (expected[attr] != undefined) is(args[attr], expected[attr], "expected service arg " + attr); } } + // If the utterance contains the phrase 'callback events', we will dispatch + // an appropriate event for each callback method. + var no_events = (aText.indexOf('callback events') < 0); + // If the utterance contains the phrase 'never end', we don't immediately + // end the 'synthesis' of the utterance. + var end_utterance = (aText.indexOf('never end') < 0); + var task = SpecialPowers.wrap(aTask); - task.setup(SpecialPowers.wrapCallbackObject(new SpeechTaskCallback())); + task.setup(SpecialPowers.wrapCallbackObject(new SpeechTaskCallback( + function() { + if (!no_events) { + task.dispatchPause(1, 1.23); + } + }, + function() { + if (!no_events) { + task.dispatchResume(1, 1.23); + } + }, + function() { + if (!no_events) { + task.dispatchEnd(1, 1.23); + } + }))); setTimeout(function () { task.dispatchStart(); - setTimeout(function () { - task.dispatchEnd(aText.length / 2.0, aText.length); - }, 0); - + if (end_utterance) { + setTimeout(function () { + task.dispatchEnd( + aText.length / 2.0, aText.length); + }, 0); + } }, 0); }, QueryInterface: function(iid) { return this; }, getInterfaces: function(c) {},
new file mode 100644 --- /dev/null +++ b/dom/media/webspeech/synth/test/file_indirect_service_events.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1155034 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1155034: Check that indirect audio services dispatch their own events</title> + <script type="application/javascript"> + window.SimpleTest = parent.SimpleTest; + window.info = parent.info; + window.is = parent.is; + window.isnot = parent.isnot; + window.ok = parent.ok; + </script> + <script type="application/javascript" src="common.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1155034">Mozilla Bug 1155034</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 1155034 **/ + +synthAddVoice('TestSpeechServiceNoAudio', 'Female 1', 'en-GB', true); + +function test_with_events() { + info('test_with_events'); + var utterance = new SpeechSynthesisUtterance("never end, callback events"); + + utterance.addEventListener('start', function(e) { + speechSynthesis.pause(); + // Wait to see if we get some bad events we didn't expect. + }); + + utterance.addEventListener('pause', function(e) { + ok(e.charIndex, 1, 'pause event charIndex matches service arguments'); + ok(e.elapsedTime, 1.23, 'pause event elapsedTime matches service arguments'); + speechSynthesis.resume(); + }); + + utterance.addEventListener('resume', function(e) { + ok(e.charIndex, 1, 'resume event charIndex matches service arguments'); + ok(e.elapsedTime, 1.23, 'resume event elapsedTime matches service arguments'); + speechSynthesis.cancel(); + }); + + utterance.addEventListener('end', function(e) { + ok(e.charIndex, 1, 'resume event charIndex matches service arguments'); + ok(e.elapsedTime, 1.23, 'end event elapsedTime matches service arguments'); + test_no_events(); + }); + + speechSynthesis.speak(utterance); +} + +function test_no_events() { + var utterance = new SpeechSynthesisUtterance("never end"); + + utterance.addEventListener('start', function(e) { + speechSynthesis.pause(); + // Wait to see if we get some bad events we didn't expect. + setTimeout(function() { + synthCleanup(); + SimpleTest.finish(); + }, 1000); + }); + + utterance.addEventListener('pause', function(e) { + ok(false, 'no pause event was explicitly dispatched from the service') + speechSynthesis.resume(); + }); + + utterance.addEventListener('resume', function(e) { + ok(false, 'no resume event was explicitly dispatched from the service') + speechSynthesis.cancel(); + }); + + utterance.addEventListener('end', function(e) { + ok(false, 'no end event was explicitly dispatched from the service') + }); + + speechSynthesis.speak(utterance); +} + +test_with_events(); + +</script> +</pre> +</body> +</html>
--- a/dom/media/webspeech/synth/test/mochitest.ini +++ b/dom/media/webspeech/synth/test/mochitest.ini @@ -1,16 +1,19 @@ [DEFAULT] skip-if = e10s support-files = common.js file_setup.html file_speech_queue.html file_speech_simple.html file_speech_cancel.html + file_indirect_service_events.html [test_setup.html] [test_speech_queue.html] skip-if = buildapp == 'b2g' # b2g(Test timed out) [test_speech_simple.html] skip-if = buildapp == 'b2g' # b2g(Test timed out) [test_speech_cancel.html] skip-if = toolkit == 'gonk' # b2g(Test timed out) +[test_indirect_service_events.html] +skip-if = toolkit == 'gonk' # b2g(Test timed out)
new file mode 100644 --- /dev/null +++ b/dom/media/webspeech/synth/test/test_indirect_service_events.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1155034 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1155034: Check that indirect audio services dispatch their own events</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="common.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1155034">Mozilla Bug 1155034</a> +<p id="display"></p> +<iframe id="testFrame"></iframe> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 1155034 **/ + +SimpleTest.waitForExplicitFinish(); + +SpecialPowers.pushPrefEnv({ set: [['media.webspeech.synth.enabled', true]] }, + function() { document.getElementById("testFrame").src = "file_indirect_service_events.html"; }); + +</script> +</pre> +</body> +</html>