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