1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27
28 #include "modules/speech/SpeechRecognition.h"
29
30 #include "bindings/v8/ExceptionState.h"
31 #include "core/dom/Document.h"
32 #include "core/dom/ExceptionCode.h"
33 #include "core/page/Page.h"
34 #include "modules/speech/SpeechRecognitionController.h"
35 #include "modules/speech/SpeechRecognitionError.h"
36 #include "modules/speech/SpeechRecognitionEvent.h"
37
38 namespace WebCore {
39
create(ExecutionContext * context)40 PassRefPtr<SpeechRecognition> SpeechRecognition::create(ExecutionContext* context)
41 {
42 RefPtr<SpeechRecognition> speechRecognition(adoptRef(new SpeechRecognition(context)));
43 speechRecognition->suspendIfNeeded();
44 return speechRecognition.release();
45 }
46
start(ExceptionState & exceptionState)47 void SpeechRecognition::start(ExceptionState& exceptionState)
48 {
49 ASSERT(m_controller);
50 if (m_started) {
51 exceptionState.throwDOMException(InvalidStateError, "recognition has already started.");
52 return;
53 }
54
55 setPendingActivity(this);
56 m_finalResults.clear();
57 m_controller->start(this, m_grammars.get(), m_lang, m_continuous, m_interimResults, m_maxAlternatives);
58 m_started = true;
59 }
60
stopFunction()61 void SpeechRecognition::stopFunction()
62 {
63 ASSERT(m_controller);
64 if (m_started && !m_stopping) {
65 m_stopping = true;
66 m_controller->stop(this);
67 }
68 }
69
abort()70 void SpeechRecognition::abort()
71 {
72 ASSERT(m_controller);
73 if (m_started && !m_stopping) {
74 m_stopping = true;
75 m_controller->abort(this);
76 }
77 }
78
didStartAudio()79 void SpeechRecognition::didStartAudio()
80 {
81 dispatchEvent(Event::create(EventTypeNames::audiostart));
82 }
83
didStartSound()84 void SpeechRecognition::didStartSound()
85 {
86 dispatchEvent(Event::create(EventTypeNames::soundstart));
87 }
88
didStartSpeech()89 void SpeechRecognition::didStartSpeech()
90 {
91 dispatchEvent(Event::create(EventTypeNames::speechstart));
92 }
93
didEndSpeech()94 void SpeechRecognition::didEndSpeech()
95 {
96 dispatchEvent(Event::create(EventTypeNames::speechend));
97 }
98
didEndSound()99 void SpeechRecognition::didEndSound()
100 {
101 dispatchEvent(Event::create(EventTypeNames::soundend));
102 }
103
didEndAudio()104 void SpeechRecognition::didEndAudio()
105 {
106 dispatchEvent(Event::create(EventTypeNames::audioend));
107 }
108
didReceiveResults(const Vector<RefPtr<SpeechRecognitionResult>> & newFinalResults,const Vector<RefPtr<SpeechRecognitionResult>> & currentInterimResults)109 void SpeechRecognition::didReceiveResults(const Vector<RefPtr<SpeechRecognitionResult> >& newFinalResults, const Vector<RefPtr<SpeechRecognitionResult> >& currentInterimResults)
110 {
111 unsigned long resultIndex = m_finalResults.size();
112
113 for (size_t i = 0; i < newFinalResults.size(); ++i)
114 m_finalResults.append(newFinalResults[i]);
115
116 Vector<RefPtr<SpeechRecognitionResult> > results = m_finalResults;
117 for (size_t i = 0; i < currentInterimResults.size(); ++i)
118 results.append(currentInterimResults[i]);
119
120 dispatchEvent(SpeechRecognitionEvent::createResult(resultIndex, results));
121 }
122
didReceiveNoMatch(PassRefPtr<SpeechRecognitionResult> result)123 void SpeechRecognition::didReceiveNoMatch(PassRefPtr<SpeechRecognitionResult> result)
124 {
125 dispatchEvent(SpeechRecognitionEvent::createNoMatch(result));
126 }
127
didReceiveError(PassRefPtr<SpeechRecognitionError> error)128 void SpeechRecognition::didReceiveError(PassRefPtr<SpeechRecognitionError> error)
129 {
130 dispatchEvent(error);
131 m_started = false;
132 }
133
didStart()134 void SpeechRecognition::didStart()
135 {
136 dispatchEvent(Event::create(EventTypeNames::start));
137 }
138
didEnd()139 void SpeechRecognition::didEnd()
140 {
141 m_started = false;
142 m_stopping = false;
143 if (!m_stoppedByActiveDOMObject)
144 dispatchEvent(Event::create(EventTypeNames::end));
145 unsetPendingActivity(this);
146 }
147
interfaceName() const148 const AtomicString& SpeechRecognition::interfaceName() const
149 {
150 return EventTargetNames::SpeechRecognition;
151 }
152
executionContext() const153 ExecutionContext* SpeechRecognition::executionContext() const
154 {
155 return ActiveDOMObject::executionContext();
156 }
157
stop()158 void SpeechRecognition::stop()
159 {
160 m_stoppedByActiveDOMObject = true;
161 if (hasPendingActivity())
162 abort();
163 }
164
SpeechRecognition(ExecutionContext * context)165 SpeechRecognition::SpeechRecognition(ExecutionContext* context)
166 : ActiveDOMObject(context)
167 , m_grammars(SpeechGrammarList::create()) // FIXME: The spec is not clear on the default value for the grammars attribute.
168 , m_continuous(false)
169 , m_interimResults(false)
170 , m_maxAlternatives(1)
171 , m_controller(0)
172 , m_stoppedByActiveDOMObject(false)
173 , m_started(false)
174 , m_stopping(false)
175 {
176 ScriptWrappable::init(this);
177 Document* document = toDocument(executionContext());
178
179 Page* page = document->page();
180 ASSERT(page);
181
182 m_controller = SpeechRecognitionController::from(page);
183 ASSERT(m_controller);
184
185 // FIXME: Need to hook up with Page to get notified when the visibility changes.
186 }
187
~SpeechRecognition()188 SpeechRecognition::~SpeechRecognition()
189 {
190 }
191
192 } // namespace WebCore
193