1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/shell/renderer/test_runner/MockWebSpeechRecognizer.h" 6 7 #include "base/logging.h" 8 #include "content/shell/renderer/test_runner/WebTestDelegate.h" 9 #include "third_party/WebKit/public/web/WebSpeechRecognitionResult.h" 10 #include "third_party/WebKit/public/web/WebSpeechRecognizerClient.h" 11 12 using namespace blink; 13 using namespace std; 14 15 namespace content { 16 17 namespace { 18 19 // Task class for calling a client function that does not take any parameters. 20 typedef void (WebSpeechRecognizerClient::*ClientFunctionPointer)(const WebSpeechRecognitionHandle&); 21 class ClientCallTask : public MockWebSpeechRecognizer::Task { 22 public: 23 ClientCallTask(MockWebSpeechRecognizer* mock, ClientFunctionPointer function) 24 : MockWebSpeechRecognizer::Task(mock) 25 , m_function(function) 26 { 27 } 28 29 virtual void run() OVERRIDE { (m_recognizer->client()->*m_function)(m_recognizer->handle()); } 30 31 private: 32 ClientFunctionPointer m_function; 33 }; 34 35 // Task for delivering a result event. 36 class ResultTask : public MockWebSpeechRecognizer::Task { 37 public: 38 ResultTask(MockWebSpeechRecognizer* mock, const WebString transcript, float confidence) 39 : MockWebSpeechRecognizer::Task(mock) 40 , m_transcript(transcript) 41 , m_confidence(confidence) 42 { 43 } 44 45 virtual void run() OVERRIDE 46 { 47 WebVector<WebString> transcripts(static_cast<size_t>(1)); 48 WebVector<float> confidences(static_cast<size_t>(1)); 49 transcripts[0] = m_transcript; 50 confidences[0] = m_confidence; 51 WebVector<WebSpeechRecognitionResult> finalResults(static_cast<size_t>(1)); 52 WebVector<WebSpeechRecognitionResult> interimResults; 53 finalResults[0].assign(transcripts, confidences, true); 54 55 m_recognizer->client()->didReceiveResults(m_recognizer->handle(), finalResults, interimResults); 56 } 57 58 private: 59 WebString m_transcript; 60 float m_confidence; 61 }; 62 63 // Task for delivering a nomatch event. 64 class NoMatchTask : public MockWebSpeechRecognizer::Task { 65 public: 66 NoMatchTask(MockWebSpeechRecognizer* mock) : MockWebSpeechRecognizer::Task(mock) { } 67 virtual void run() OVERRIDE { m_recognizer->client()->didReceiveNoMatch(m_recognizer->handle(), WebSpeechRecognitionResult()); } 68 }; 69 70 // Task for delivering an error event. 71 class ErrorTask : public MockWebSpeechRecognizer::Task { 72 public: 73 ErrorTask(MockWebSpeechRecognizer* mock, WebSpeechRecognizerClient::ErrorCode code, const WebString& message) 74 : MockWebSpeechRecognizer::Task(mock) 75 , m_code(code) 76 , m_message(message) 77 { 78 } 79 80 virtual void run() OVERRIDE { m_recognizer->client()->didReceiveError(m_recognizer->handle(), m_message, m_code); } 81 82 private: 83 WebSpeechRecognizerClient::ErrorCode m_code; 84 WebString m_message; 85 }; 86 87 } // namespace 88 89 MockWebSpeechRecognizer::MockWebSpeechRecognizer() 90 : m_wasAborted(false) 91 , m_taskQueueRunning(false) 92 , m_delegate(0) 93 { 94 } 95 96 MockWebSpeechRecognizer::~MockWebSpeechRecognizer() 97 { 98 clearTaskQueue(); 99 } 100 101 void MockWebSpeechRecognizer::setDelegate(WebTestDelegate* delegate) 102 { 103 m_delegate = delegate; 104 } 105 106 void MockWebSpeechRecognizer::start(const WebSpeechRecognitionHandle& handle, const WebSpeechRecognitionParams& params, WebSpeechRecognizerClient* client) 107 { 108 m_wasAborted = false; 109 m_handle = handle; 110 m_client = client; 111 112 m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didStart)); 113 m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didStartAudio)); 114 m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didStartSound)); 115 116 if (!m_mockTranscripts.empty()) { 117 DCHECK_EQ(m_mockTranscripts.size(), m_mockConfidences.size()); 118 119 for (size_t i = 0; i < m_mockTranscripts.size(); ++i) 120 m_taskQueue.push_back(new ResultTask(this, m_mockTranscripts[i], m_mockConfidences[i])); 121 122 m_mockTranscripts.clear(); 123 m_mockConfidences.clear(); 124 } else 125 m_taskQueue.push_back(new NoMatchTask(this)); 126 127 m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEndSound)); 128 m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEndAudio)); 129 m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEnd)); 130 131 startTaskQueue(); 132 } 133 134 void MockWebSpeechRecognizer::stop(const WebSpeechRecognitionHandle& handle, WebSpeechRecognizerClient* client) 135 { 136 m_handle = handle; 137 m_client = client; 138 139 // FIXME: Implement. 140 NOTREACHED(); 141 } 142 143 void MockWebSpeechRecognizer::abort(const WebSpeechRecognitionHandle& handle, WebSpeechRecognizerClient* client) 144 { 145 m_handle = handle; 146 m_client = client; 147 148 clearTaskQueue(); 149 m_wasAborted = true; 150 m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEnd)); 151 startTaskQueue(); 152 } 153 154 void MockWebSpeechRecognizer::addMockResult(const WebString& transcript, float confidence) 155 { 156 m_mockTranscripts.push_back(transcript); 157 m_mockConfidences.push_back(confidence); 158 } 159 160 void MockWebSpeechRecognizer::setError(const WebString& error, const WebString& message) 161 { 162 WebSpeechRecognizerClient::ErrorCode code; 163 if (error == "OtherError") 164 code = WebSpeechRecognizerClient::OtherError; 165 else if (error == "NoSpeechError") 166 code = WebSpeechRecognizerClient::NoSpeechError; 167 else if (error == "AbortedError") 168 code = WebSpeechRecognizerClient::AbortedError; 169 else if (error == "AudioCaptureError") 170 code = WebSpeechRecognizerClient::AudioCaptureError; 171 else if (error == "NetworkError") 172 code = WebSpeechRecognizerClient::NetworkError; 173 else if (error == "NotAllowedError") 174 code = WebSpeechRecognizerClient::NotAllowedError; 175 else if (error == "ServiceNotAllowedError") 176 code = WebSpeechRecognizerClient::ServiceNotAllowedError; 177 else if (error == "BadGrammarError") 178 code = WebSpeechRecognizerClient::BadGrammarError; 179 else if (error == "LanguageNotSupportedError") 180 code = WebSpeechRecognizerClient::LanguageNotSupportedError; 181 else 182 return; 183 184 clearTaskQueue(); 185 m_taskQueue.push_back(new ErrorTask(this, code, message)); 186 m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEnd)); 187 startTaskQueue(); 188 } 189 190 void MockWebSpeechRecognizer::startTaskQueue() 191 { 192 if (m_taskQueueRunning) 193 return; 194 m_delegate->postTask(new StepTask(this)); 195 m_taskQueueRunning = true; 196 } 197 198 void MockWebSpeechRecognizer::clearTaskQueue() 199 { 200 while (!m_taskQueue.empty()) { 201 delete m_taskQueue.front(); 202 m_taskQueue.pop_front(); 203 } 204 m_taskQueueRunning = false; 205 } 206 207 void MockWebSpeechRecognizer::StepTask::runIfValid() 208 { 209 if (m_object->m_taskQueue.empty()) { 210 m_object->m_taskQueueRunning = false; 211 return; 212 } 213 214 Task* task = m_object->m_taskQueue.front(); 215 m_object->m_taskQueue.pop_front(); 216 task->run(); 217 delete task; 218 219 if (m_object->m_taskQueue.empty()) { 220 m_object->m_taskQueueRunning = false; 221 return; 222 } 223 224 m_object->m_delegate->postTask(new StepTask(m_object)); 225 } 226 227 } // namespace content 228