mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 1155034 - Let indirect audio speech services send their own events. Make pause/resume IPC safe. r=smaug
This commit is contained in:
parent
7f088bfbe8
commit
21b7ceb7e9
@ -196,7 +196,7 @@ SpeechSynthesis::Cancel()
|
||||
void
|
||||
SpeechSynthesis::Pause()
|
||||
{
|
||||
if (mCurrentTask) {
|
||||
if (mCurrentTask && !Paused() && (Speaking() || Pending())) {
|
||||
mCurrentTask->Pause();
|
||||
}
|
||||
}
|
||||
@ -204,7 +204,7 @@ SpeechSynthesis::Pause()
|
||||
void
|
||||
SpeechSynthesis::Resume()
|
||||
{
|
||||
if (mCurrentTask) {
|
||||
if (mCurrentTask && Paused()) {
|
||||
mCurrentTask->Resume();
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ interface nsISpeechTask : nsISupports
|
||||
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.
|
||||
@ -86,7 +86,7 @@ interface nsISpeechTask : nsISupports
|
||||
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.
|
||||
|
@ -474,11 +474,6 @@ 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");
|
||||
@ -486,9 +481,8 @@ nsSpeechTask::Pause()
|
||||
|
||||
if (mStream) {
|
||||
mStream->ChangeExplicitBlockerCount(1);
|
||||
DispatchPauseImpl(GetCurrentTime(), GetCurrentCharOffset());
|
||||
}
|
||||
|
||||
DispatchPauseImpl(GetCurrentTime(), GetCurrentCharOffset());
|
||||
}
|
||||
|
||||
void
|
||||
@ -496,10 +490,6 @@ 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");
|
||||
@ -507,9 +497,8 @@ nsSpeechTask::Resume()
|
||||
|
||||
if (mStream) {
|
||||
mStream->ChangeExplicitBlockerCount(-1);
|
||||
DispatchResumeImpl(GetCurrentTime(), GetCurrentCharOffset());
|
||||
}
|
||||
|
||||
DispatchResumeImpl(GetCurrentTime(), GetCurrentCharOffset());
|
||||
}
|
||||
|
||||
void
|
||||
@ -526,9 +515,8 @@ nsSpeechTask::Cancel()
|
||||
|
||||
if (mStream) {
|
||||
mStream->ChangeExplicitBlockerCount(1);
|
||||
DispatchEndImpl(GetCurrentTime(), GetCurrentCharOffset());
|
||||
}
|
||||
|
||||
DispatchEndImpl(GetCurrentTime(), GetCurrentCharOffset());
|
||||
}
|
||||
|
||||
float
|
||||
|
@ -81,14 +81,38 @@ var TestSpeechServiceNoAudio = SpecialPowers.wrapCallbackObject({
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
},
|
||||
|
||||
|
@ -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>
|
@ -6,6 +6,7 @@ support-files =
|
||||
file_speech_queue.html
|
||||
file_speech_simple.html
|
||||
file_speech_cancel.html
|
||||
file_indirect_service_events.html
|
||||
|
||||
[test_setup.html]
|
||||
[test_speech_queue.html]
|
||||
@ -14,3 +15,5 @@ skip-if = buildapp == 'b2g' # b2g(Test timed out)
|
||||
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)
|
||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user