Diff
Modified: trunk/LayoutTests/ChangeLog (144219 => 144220)
--- trunk/LayoutTests/ChangeLog 2013-02-27 20:11:40 UTC (rev 144219)
+++ trunk/LayoutTests/ChangeLog 2013-02-27 20:14:45 UTC (rev 144220)
@@ -1,3 +1,13 @@
+2013-02-27 Chris Fleizach <[email protected]>
+
+ WebSpeech: Support pause/resume ability
+ https://bugs.webkit.org/show_bug.cgi?id=107345
+
+ Reviewed by Beth Dakin.
+
+ * platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume-expected.txt: Added.
+ * platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume.html: Added.
+
2013-02-27 Stephen Chenney <[email protected]>
[Chromium] Test expectations updates
Added: trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume-expected.txt (0 => 144220)
--- trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume-expected.txt 2013-02-27 20:14:45 UTC (rev 144220)
@@ -0,0 +1,18 @@
+This tests that pausing/resuming speech jobs works as expected.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+On pause event received.
+PASS speechSynthesis.paused is true
+PASS speechSynthesis.speaking is true
+On resume event received.
+PASS speechSynthesis.paused is false
+PASS speechSynthesis.speaking is true
+On end event received.
+PASS speechSynthesis.paused is false
+PASS speechSynthesis.speaking is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume.html (0 => 144220)
--- trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume.html (rev 0)
+++ trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume.html 2013-02-27 20:14:45 UTC (rev 144220)
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body id="body">
+
+<div id="console"></div>
+
+<script>
+
+ description("This tests that pausing/resuming speech jobs works as expected.");
+
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+ if (window.internals)
+ window.internals.enableMockSpeechSynthesizer();
+
+ window.jsTestIsAsync = true;
+
+ var u = new SpeechSynthesisUtterance("this is a test");
+
+ // Verify that callbacks and state are correct for paused and speaking states.
+ u._onpause_ = function(event) {
+ debug("On pause event received.");
+ shouldBeTrue("speechSynthesis.paused");
+ shouldBeTrue("speechSynthesis.speaking");
+ }
+
+ u._onresume_ = function(event) {
+ debug("On resume event received.");
+ shouldBeFalse("speechSynthesis.paused");
+ shouldBeTrue("speechSynthesis.speaking");
+ }
+
+ u._onend_ = function(event) {
+ debug("On end event received.");
+ shouldBeFalse("speechSynthesis.paused");
+ shouldBeFalse("speechSynthesis.speaking");
+ finishJSTest();
+ }
+
+ speechSynthesis.speak(u);
+
+ // Quickly pause and resume the speech job.
+ setTimeout("speechSynthesis.pause()", "1");
+ setTimeout("speechSynthesis.resume()", "2");
+
+</script>
+
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (144219 => 144220)
--- trunk/Source/WebCore/ChangeLog 2013-02-27 20:11:40 UTC (rev 144219)
+++ trunk/Source/WebCore/ChangeLog 2013-02-27 20:14:45 UTC (rev 144220)
@@ -1,3 +1,39 @@
+2013-02-27 Chris Fleizach <[email protected]>
+
+ WebSpeech: Support pause/resume ability
+ https://bugs.webkit.org/show_bug.cgi?id=107345
+
+ Reviewed by Beth Dakin.
+
+ Add in the pause/resume functionality to SpeechSynthesis. Also hook up
+ the callback events.
+
+ Test: platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume.html
+
+ * Modules/speech/SpeechSynthesis.cpp:
+ (WebCore::SpeechSynthesis::SpeechSynthesis):
+ (WebCore::SpeechSynthesis::pending):
+ (WebCore::SpeechSynthesis::paused):
+ (WebCore::SpeechSynthesis::startSpeakingImmediately):
+ (WebCore::SpeechSynthesis::pause):
+ (WebCore::SpeechSynthesis::resume):
+ (WebCore):
+ (WebCore::SpeechSynthesis::didPauseSpeaking):
+ (WebCore::SpeechSynthesis::didResumeSpeaking):
+ * Modules/speech/SpeechSynthesis.h:
+ (SpeechSynthesis):
+ * platform/PlatformSpeechSynthesizer.h:
+ (PlatformSpeechSynthesizerClient):
+ (PlatformSpeechSynthesizer):
+ * platform/mac/PlatformSpeechSynthesizerMac.mm:
+ (-[WebSpeechSynthesisWrapper speakUtterance:WebCore::]):
+ (-[WebSpeechSynthesisWrapper pause]):
+ (-[WebSpeechSynthesisWrapper resume]):
+ (-[WebSpeechSynthesisWrapper speechSynthesizer:didFinishSpeaking:]):
+ (WebCore::PlatformSpeechSynthesizer::pause):
+ (WebCore):
+ (WebCore::PlatformSpeechSynthesizer::resume):
+
2013-02-26 Alexey Proskuryakov <[email protected]>
Don't add a body to platform request until necessary
Modified: trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp (144219 => 144220)
--- trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp 2013-02-27 20:11:40 UTC (rev 144219)
+++ trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp 2013-02-27 20:14:45 UTC (rev 144220)
@@ -44,6 +44,7 @@
SpeechSynthesis::SpeechSynthesis()
: m_platformSpeechSynthesizer(PlatformSpeechSynthesizer::create(this))
, m_currentSpeechUtterance(0)
+ , m_isPaused(false)
{
}
@@ -80,12 +81,14 @@
bool SpeechSynthesis::pending() const
{
- return false;
+ // This is true if there are any utterances that have not started.
+ // That means there will be more than one in the queue.
+ return m_utteranceQueue.size() > 1;
}
bool SpeechSynthesis::paused() const
{
- return false;
+ return m_isPaused;
}
void SpeechSynthesis::startSpeakingImmediately(SpeechSynthesisUtterance* utterance)
@@ -93,6 +96,7 @@
ASSERT(!m_currentSpeechUtterance);
utterance->setStartTime(monotonicallyIncreasingTime());
m_currentSpeechUtterance = utterance;
+ m_isPaused = false;
m_platformSpeechSynthesizer->speak(utterance->platformUtterance());
}
@@ -111,10 +115,13 @@
void SpeechSynthesis::pause()
{
+ if (!m_isPaused)
+ m_platformSpeechSynthesizer->pause();
}
void SpeechSynthesis::resume()
{
+ m_platformSpeechSynthesizer->resume();
}
void SpeechSynthesis::fireEvent(const AtomicString& type, SpeechSynthesisUtterance* utterance, unsigned long charIndex, const String& name)
@@ -144,7 +151,19 @@
{
fireEvent(eventNames().startEvent, static_cast<SpeechSynthesisUtterance*>(utterance->client()), 0, String());
}
+
+void SpeechSynthesis::didPauseSpeaking(const PlatformSpeechSynthesisUtterance* utterance)
+{
+ m_isPaused = true;
+ fireEvent(eventNames().pauseEvent, static_cast<SpeechSynthesisUtterance*>(utterance->client()), 0, String());
+}
+void SpeechSynthesis::didResumeSpeaking(const PlatformSpeechSynthesisUtterance* utterance)
+{
+ m_isPaused = false;
+ fireEvent(eventNames().resumeEvent, static_cast<SpeechSynthesisUtterance*>(utterance->client()), 0, String());
+}
+
void SpeechSynthesis::didFinishSpeaking(const PlatformSpeechSynthesisUtterance* utterance)
{
handleSpeakingCompleted(static_cast<SpeechSynthesisUtterance*>(utterance->client()), false);
Modified: trunk/Source/WebCore/Modules/speech/SpeechSynthesis.h (144219 => 144220)
--- trunk/Source/WebCore/Modules/speech/SpeechSynthesis.h 2013-02-27 20:11:40 UTC (rev 144219)
+++ trunk/Source/WebCore/Modules/speech/SpeechSynthesis.h 2013-02-27 20:14:45 UTC (rev 144220)
@@ -66,6 +66,8 @@
// PlatformSpeechSynthesizerClient override methods.
virtual void voicesDidChange() OVERRIDE;
virtual void didStartSpeaking(const PlatformSpeechSynthesisUtterance*) OVERRIDE;
+ virtual void didPauseSpeaking(const PlatformSpeechSynthesisUtterance*) OVERRIDE;
+ virtual void didResumeSpeaking(const PlatformSpeechSynthesisUtterance*) OVERRIDE;
virtual void didFinishSpeaking(const PlatformSpeechSynthesisUtterance*) OVERRIDE;
virtual void speakingErrorOccurred(const PlatformSpeechSynthesisUtterance*) OVERRIDE;
@@ -77,7 +79,7 @@
Vector<RefPtr<SpeechSynthesisVoice> > m_voiceList;
SpeechSynthesisUtterance* m_currentSpeechUtterance;
Deque<RefPtr<SpeechSynthesisUtterance> > m_utteranceQueue;
-
+ bool m_isPaused;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/PlatformSpeechSynthesizer.h (144219 => 144220)
--- trunk/Source/WebCore/platform/PlatformSpeechSynthesizer.h 2013-02-27 20:11:40 UTC (rev 144219)
+++ trunk/Source/WebCore/platform/PlatformSpeechSynthesizer.h 2013-02-27 20:14:45 UTC (rev 144220)
@@ -45,6 +45,8 @@
public:
virtual void didStartSpeaking(const PlatformSpeechSynthesisUtterance*) = 0;
virtual void didFinishSpeaking(const PlatformSpeechSynthesisUtterance*) = 0;
+ virtual void didPauseSpeaking(const PlatformSpeechSynthesisUtterance*) = 0;
+ virtual void didResumeSpeaking(const PlatformSpeechSynthesisUtterance*) = 0;
virtual void speakingErrorOccurred(const PlatformSpeechSynthesisUtterance*) = 0;
virtual void voicesDidChange() = 0;
@@ -60,6 +62,8 @@
const Vector<RefPtr<PlatformSpeechSynthesisVoice> >& voiceList() const { return m_voiceList; }
virtual void speak(const PlatformSpeechSynthesisUtterance&);
+ virtual void pause();
+ virtual void resume();
PlatformSpeechSynthesizerClient* client() const { return m_speechSynthesizerClient; }
Modified: trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm (144219 => 144220)
--- trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm 2013-02-27 20:11:40 UTC (rev 144219)
+++ trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm 2013-02-27 20:14:45 UTC (rev 144220)
@@ -98,12 +98,18 @@
}
}
+ NSString *voiceURI = nil;
if (utteranceVoiceByURI)
- [m_synthesizer setVoice:utteranceVoiceByURI->voiceURI()];
+ voiceURI = utteranceVoiceByURI->voiceURI();
else if (utteranceVoiceByLanguage)
- [m_synthesizer setVoice:utteranceVoiceByLanguage->voiceURI()];
+ voiceURI = utteranceVoiceByLanguage->voiceURI();
else
- [m_synthesizer setVoice:[NSSpeechSynthesizer defaultVoice]];
+ voiceURI = [NSSpeechSynthesizer defaultVoice];
+
+ // Don't set the voice unless necessary. There's a bug in NSSpeechSynthesizer such that
+ // setting the voice for the first time will cause the first speechDone callback to report it was unsuccessful.
+ if (![[m_synthesizer voice] isEqualToString:voiceURI])
+ [m_synthesizer setVoice:voiceURI];
[m_synthesizer setRate:[self convertRateToWPM:utterance->rate()]];
[m_synthesizer setVolume:utterance->volume()];
@@ -113,8 +119,27 @@
m_synthesizerObject->client()->didStartSpeaking(utterance);
}
+- (void)pause
+{
+ if (!m_utterance)
+ return;
+
+ [m_synthesizer pauseSpeakingAtBoundary:NSSpeechImmediateBoundary];
+ m_synthesizerObject->client()->didPauseSpeaking(m_utterance);
+}
+
+- (void)resume
+{
+ if (!m_utterance)
+ return;
+
+ [m_synthesizer continueSpeaking];
+ m_synthesizerObject->client()->didResumeSpeaking(m_utterance);
+}
+
- (void)speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:(BOOL)finishedSpeaking
{
+ ASSERT(m_utterance);
UNUSED_PARAM(sender);
// Clear the m_utterance variable in case finish speaking kicks off a new speaking job immediately.
@@ -153,6 +178,16 @@
}
}
+void PlatformSpeechSynthesizer::pause()
+{
+ [m_platformSpeechWrapper.get() pause];
+}
+
+void PlatformSpeechSynthesizer::resume()
+{
+ [m_platformSpeechWrapper.get() resume];
+}
+
void PlatformSpeechSynthesizer::speak(const PlatformSpeechSynthesisUtterance& utterance)
{
if (!m_platformSpeechWrapper)
Modified: trunk/Source/WebCore/platform/mock/PlatformSpeechSynthesizerMock.cpp (144219 => 144220)
--- trunk/Source/WebCore/platform/mock/PlatformSpeechSynthesizerMock.cpp 2013-02-27 20:11:40 UTC (rev 144219)
+++ trunk/Source/WebCore/platform/mock/PlatformSpeechSynthesizerMock.cpp 2013-02-27 20:14:45 UTC (rev 144220)
@@ -65,9 +65,22 @@
{
m_utterance = &utterance;
client()->didStartSpeaking(m_utterance);
- m_speakingFinishedTimer.startOneShot(0);
+
+ // Give the fake speech job some time so that pause and other functions have time to be called.
+ m_speakingFinishedTimer.startOneShot(.1);
}
+void PlatformSpeechSynthesizerMock::pause()
+{
+ client()->didPauseSpeaking(m_utterance);
+}
+
+void PlatformSpeechSynthesizerMock::resume()
+{
+ client()->didResumeSpeaking(m_utterance);
+}
+
+
} // namespace WebCore
#endif // ENABLE(SPEECH_SYNTHESIS)
Modified: trunk/Source/WebCore/platform/mock/PlatformSpeechSynthesizerMock.h (144219 => 144220)
--- trunk/Source/WebCore/platform/mock/PlatformSpeechSynthesizerMock.h 2013-02-27 20:11:40 UTC (rev 144219)
+++ trunk/Source/WebCore/platform/mock/PlatformSpeechSynthesizerMock.h 2013-02-27 20:14:45 UTC (rev 144220)
@@ -40,6 +40,8 @@
virtual ~PlatformSpeechSynthesizerMock();
virtual void speak(const PlatformSpeechSynthesisUtterance&);
+ virtual void pause();
+ virtual void resume();
private:
explicit PlatformSpeechSynthesizerMock(PlatformSpeechSynthesizerClient*);