// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/test_runner/mock_web_speech_recognizer.h" #include "base/logging.h" #include "components/test_runner/web_test_delegate.h" #include "third_party/WebKit/public/web/WebSpeechRecognitionResult.h" #include "third_party/WebKit/public/web/WebSpeechRecognizerClient.h" namespace test_runner { namespace { // Task class for calling a client function that does not take any parameters. typedef void (blink::WebSpeechRecognizerClient::*ClientFunctionPointer)( const blink::WebSpeechRecognitionHandle&); class ClientCallTask : public MockWebSpeechRecognizer::Task { public: ClientCallTask(MockWebSpeechRecognizer* mock, ClientFunctionPointer function) : MockWebSpeechRecognizer::Task(mock), function_(function) {} ~ClientCallTask() override {} void run() override { (recognizer_->Client()->*function_)(recognizer_->Handle()); } private: ClientFunctionPointer function_; DISALLOW_COPY_AND_ASSIGN(ClientCallTask); }; // Task for delivering a result event. class ResultTask : public MockWebSpeechRecognizer::Task { public: ResultTask(MockWebSpeechRecognizer* mock, const blink::WebString transcript, float confidence) : MockWebSpeechRecognizer::Task(mock), transcript_(transcript), confidence_(confidence) {} ~ResultTask() override {} void run() override { blink::WebVector transcripts(static_cast(1)); blink::WebVector confidences(static_cast(1)); transcripts[0] = transcript_; confidences[0] = confidence_; blink::WebVector final_results( static_cast(1)); blink::WebVector interim_results; final_results[0].assign(transcripts, confidences, true); recognizer_->Client()->didReceiveResults( recognizer_->Handle(), final_results, interim_results); } private: blink::WebString transcript_; float confidence_; DISALLOW_COPY_AND_ASSIGN(ResultTask); }; // Task for delivering a nomatch event. class NoMatchTask : public MockWebSpeechRecognizer::Task { public: NoMatchTask(MockWebSpeechRecognizer* mock) : MockWebSpeechRecognizer::Task(mock) {} ~NoMatchTask() override {} void run() override { recognizer_->Client()->didReceiveNoMatch( recognizer_->Handle(), blink::WebSpeechRecognitionResult()); } private: DISALLOW_COPY_AND_ASSIGN(NoMatchTask); }; // Task for delivering an error event. class ErrorTask : public MockWebSpeechRecognizer::Task { public: ErrorTask(MockWebSpeechRecognizer* mock, blink::WebSpeechRecognizerClient::ErrorCode code, const blink::WebString& message) : MockWebSpeechRecognizer::Task(mock), code_(code), message_(message) {} ~ErrorTask() override {} void run() override { recognizer_->Client()->didReceiveError( recognizer_->Handle(), message_, code_); } private: blink::WebSpeechRecognizerClient::ErrorCode code_; blink::WebString message_; DISALLOW_COPY_AND_ASSIGN(ErrorTask); }; } // namespace MockWebSpeechRecognizer::MockWebSpeechRecognizer() : was_aborted_(false), task_queue_running_(false), delegate_(0) { } MockWebSpeechRecognizer::~MockWebSpeechRecognizer() { ClearTaskQueue(); } void MockWebSpeechRecognizer::SetDelegate(WebTestDelegate* delegate) { delegate_ = delegate; } void MockWebSpeechRecognizer::start( const blink::WebSpeechRecognitionHandle& handle, const blink::WebSpeechRecognitionParams& params, blink::WebSpeechRecognizerClient* client) { was_aborted_ = false; handle_ = handle; client_ = client; task_queue_.push_back( new ClientCallTask(this, &blink::WebSpeechRecognizerClient::didStart)); task_queue_.push_back(new ClientCallTask( this, &blink::WebSpeechRecognizerClient::didStartAudio)); task_queue_.push_back(new ClientCallTask( this, &blink::WebSpeechRecognizerClient::didStartSound)); if (!mock_transcripts_.empty()) { DCHECK_EQ(mock_transcripts_.size(), mock_confidences_.size()); for (size_t i = 0; i < mock_transcripts_.size(); ++i) task_queue_.push_back( new ResultTask(this, mock_transcripts_[i], mock_confidences_[i])); mock_transcripts_.clear(); mock_confidences_.clear(); } else task_queue_.push_back(new NoMatchTask(this)); task_queue_.push_back( new ClientCallTask(this, &blink::WebSpeechRecognizerClient::didEndSound)); task_queue_.push_back( new ClientCallTask(this, &blink::WebSpeechRecognizerClient::didEndAudio)); task_queue_.push_back( new ClientCallTask(this, &blink::WebSpeechRecognizerClient::didEnd)); StartTaskQueue(); } void MockWebSpeechRecognizer::stop( const blink::WebSpeechRecognitionHandle& handle, blink::WebSpeechRecognizerClient* client) { handle_ = handle; client_ = client; // FIXME: Implement. NOTREACHED(); } void MockWebSpeechRecognizer::abort( const blink::WebSpeechRecognitionHandle& handle, blink::WebSpeechRecognizerClient* client) { handle_ = handle; client_ = client; ClearTaskQueue(); was_aborted_ = true; task_queue_.push_back( new ClientCallTask(this, &blink::WebSpeechRecognizerClient::didEnd)); StartTaskQueue(); } void MockWebSpeechRecognizer::AddMockResult(const blink::WebString& transcript, float confidence) { mock_transcripts_.push_back(transcript); mock_confidences_.push_back(confidence); } void MockWebSpeechRecognizer::SetError(const blink::WebString& error, const blink::WebString& message) { blink::WebSpeechRecognizerClient::ErrorCode code; if (error == "OtherError") code = blink::WebSpeechRecognizerClient::OtherError; else if (error == "NoSpeechError") code = blink::WebSpeechRecognizerClient::NoSpeechError; else if (error == "AbortedError") code = blink::WebSpeechRecognizerClient::AbortedError; else if (error == "AudioCaptureError") code = blink::WebSpeechRecognizerClient::AudioCaptureError; else if (error == "NetworkError") code = blink::WebSpeechRecognizerClient::NetworkError; else if (error == "NotAllowedError") code = blink::WebSpeechRecognizerClient::NotAllowedError; else if (error == "ServiceNotAllowedError") code = blink::WebSpeechRecognizerClient::ServiceNotAllowedError; else if (error == "BadGrammarError") code = blink::WebSpeechRecognizerClient::BadGrammarError; else if (error == "LanguageNotSupportedError") code = blink::WebSpeechRecognizerClient::LanguageNotSupportedError; else return; ClearTaskQueue(); task_queue_.push_back(new ErrorTask(this, code, message)); task_queue_.push_back( new ClientCallTask(this, &blink::WebSpeechRecognizerClient::didEnd)); StartTaskQueue(); } void MockWebSpeechRecognizer::StartTaskQueue() { if (task_queue_running_) return; delegate_->PostTask(new StepTask(this)); task_queue_running_ = true; } void MockWebSpeechRecognizer::ClearTaskQueue() { while (!task_queue_.empty()) { delete task_queue_.front(); task_queue_.pop_front(); } task_queue_running_ = false; } void MockWebSpeechRecognizer::StepTask::RunIfValid() { if (object_->task_queue_.empty()) { object_->task_queue_running_ = false; return; } Task* task = object_->task_queue_.front(); object_->task_queue_.pop_front(); task->run(); delete task; if (object_->task_queue_.empty()) { object_->task_queue_running_ = false; return; } object_->delegate_->PostTask(new StepTask(object_)); } } // namespace test_runner