Title: [144220] trunk
Revision
144220
Author
[email protected]
Date
2013-02-27 12:14:45 -0800 (Wed, 27 Feb 2013)

Log Message

WebSpeech: Support pause/resume ability
https://bugs.webkit.org/show_bug.cgi?id=107345

Reviewed by Beth Dakin.

Source/WebCore:

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):

LayoutTests:

* platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume-expected.txt: Added.
* platform/mac/fast/speechsynthesis/speech-synthesis-pause-resume.html: Added.

Modified Paths

Added Paths

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*);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to