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 38namespace WebCore { 39 40PassRefPtr<SpeechRecognition> SpeechRecognition::create(ScriptExecutionContext* context) 41{ 42 RefPtr<SpeechRecognition> speechRecognition(adoptRef(new SpeechRecognition(context))); 43 speechRecognition->suspendIfNeeded(); 44 return speechRecognition.release(); 45} 46 47void SpeechRecognition::start(ExceptionState& es) 48{ 49 ASSERT(m_controller); 50 if (m_started) { 51 es.throwDOMException(InvalidStateError); 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 61void 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 70void 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 79void SpeechRecognition::didStartAudio() 80{ 81 dispatchEvent(Event::create(eventNames().audiostartEvent, /*canBubble=*/false, /*cancelable=*/false)); 82} 83 84void SpeechRecognition::didStartSound() 85{ 86 dispatchEvent(Event::create(eventNames().soundstartEvent, /*canBubble=*/false, /*cancelable=*/false)); 87} 88 89void SpeechRecognition::didStartSpeech() 90{ 91 dispatchEvent(Event::create(eventNames().speechstartEvent, /*canBubble=*/false, /*cancelable=*/false)); 92} 93 94void SpeechRecognition::didEndSpeech() 95{ 96 dispatchEvent(Event::create(eventNames().speechendEvent, /*canBubble=*/false, /*cancelable=*/false)); 97} 98 99void SpeechRecognition::didEndSound() 100{ 101 dispatchEvent(Event::create(eventNames().soundendEvent, /*canBubble=*/false, /*cancelable=*/false)); 102} 103 104void SpeechRecognition::didEndAudio() 105{ 106 dispatchEvent(Event::create(eventNames().audioendEvent, /*canBubble=*/false, /*cancelable=*/false)); 107} 108 109void 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 123void SpeechRecognition::didReceiveNoMatch(PassRefPtr<SpeechRecognitionResult> result) 124{ 125 dispatchEvent(SpeechRecognitionEvent::createNoMatch(result)); 126} 127 128void SpeechRecognition::didReceiveError(PassRefPtr<SpeechRecognitionError> error) 129{ 130 dispatchEvent(error); 131 m_started = false; 132} 133 134void SpeechRecognition::didStart() 135{ 136 dispatchEvent(Event::create(eventNames().startEvent, /*canBubble=*/false, /*cancelable=*/false)); 137} 138 139void SpeechRecognition::didEnd() 140{ 141 m_started = false; 142 m_stopping = false; 143 if (!m_stoppedByActiveDOMObject) 144 dispatchEvent(Event::create(eventNames().endEvent, /*canBubble=*/false, /*cancelable=*/false)); 145 unsetPendingActivity(this); 146} 147 148const AtomicString& SpeechRecognition::interfaceName() const 149{ 150 return eventNames().interfaceForSpeechRecognition; 151} 152 153ScriptExecutionContext* SpeechRecognition::scriptExecutionContext() const 154{ 155 return ActiveDOMObject::scriptExecutionContext(); 156} 157 158void SpeechRecognition::stop() 159{ 160 m_stoppedByActiveDOMObject = true; 161 if (hasPendingActivity()) 162 abort(); 163} 164 165SpeechRecognition::SpeechRecognition(ScriptExecutionContext* 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(scriptExecutionContext()); 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 188SpeechRecognition::~SpeechRecognition() 189{ 190} 191 192} // namespace WebCore 193