• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "MockWebSpeechInputController.h"
27 
28 #include "public/platform/WebCString.h"
29 #include "public/platform/WebVector.h"
30 #include "public/testing/WebTestDelegate.h"
31 #include "public/web/WebSpeechInputListener.h"
32 
33 #if ENABLE_INPUT_SPEECH
34 
35 using namespace blink;
36 using namespace std;
37 
38 namespace WebTestRunner {
39 
40 namespace {
41 
makeRectResult(const WebRect & rect)42 WebSpeechInputResultArray makeRectResult(const WebRect& rect)
43 {
44     char buffer[100];
45     snprintf(buffer, sizeof(buffer), "%d,%d,%d,%d", rect.x, rect.y, rect.width, rect.height);
46 
47     WebSpeechInputResult res;
48     res.assign(WebString::fromUTF8(static_cast<const char*>(buffer)), 1.0);
49 
50     WebSpeechInputResultArray results;
51     results.assign(&res, 1);
52     return results;
53 }
54 
55 }
56 
MockWebSpeechInputController(WebSpeechInputListener * listener)57 MockWebSpeechInputController::MockWebSpeechInputController(WebSpeechInputListener* listener)
58     : m_listener(listener)
59     , m_speechTask(0)
60     , m_recording(false)
61     , m_requestId(-1)
62     , m_dumpRect(false)
63     , m_delegate(0)
64 {
65 }
66 
~MockWebSpeechInputController()67 MockWebSpeechInputController::~MockWebSpeechInputController()
68 {
69 }
70 
setDelegate(WebTestDelegate * delegate)71 void MockWebSpeechInputController::setDelegate(WebTestDelegate* delegate)
72 {
73     m_delegate = delegate;
74 }
75 
addMockRecognitionResult(const WebString & result,double confidence,const WebString & language)76 void MockWebSpeechInputController::addMockRecognitionResult(const WebString& result, double confidence, const WebString& language)
77 {
78     WebSpeechInputResult res;
79     res.assign(result, confidence);
80 
81     if (language.isEmpty())
82         m_resultsForEmptyLanguage.push_back(res);
83     else {
84         string langString = language.utf8();
85         if (m_recognitionResults.find(langString) == m_recognitionResults.end())
86             m_recognitionResults[langString] = vector<WebSpeechInputResult>();
87         m_recognitionResults[langString].push_back(res);
88     }
89 }
90 
setDumpRect(bool dumpRect)91 void MockWebSpeechInputController::setDumpRect(bool dumpRect)
92 {
93     m_dumpRect = dumpRect;
94 }
95 
clearResults()96 void MockWebSpeechInputController::clearResults()
97 {
98     m_resultsForEmptyLanguage.clear();
99     m_recognitionResults.clear();
100     m_dumpRect = false;
101 }
102 
startRecognition(int requestId,const WebRect & elementRect,const WebString & language,const WebString & grammar,const WebSecurityOrigin & origin)103 bool MockWebSpeechInputController::startRecognition(int requestId, const WebRect& elementRect, const WebString& language, const WebString& grammar, const WebSecurityOrigin& origin)
104 {
105     if (m_speechTask)
106         return false;
107 
108     m_requestId = requestId;
109     m_requestRect = elementRect;
110     m_recording = true;
111     m_language = language.utf8();
112 
113     m_speechTask = new SpeechTask(this);
114     m_delegate->postTask(m_speechTask);
115 
116     return true;
117 }
118 
cancelRecognition(int requestId)119 void MockWebSpeechInputController::cancelRecognition(int requestId)
120 {
121     if (m_speechTask) {
122         BLINK_ASSERT(requestId == m_requestId);
123 
124         m_speechTask->stop();
125         m_recording = false;
126         m_listener->didCompleteRecognition(m_requestId);
127         m_requestId = 0;
128     }
129 }
130 
stopRecording(int requestId)131 void MockWebSpeechInputController::stopRecording(int requestId)
132 {
133     BLINK_ASSERT(requestId == m_requestId);
134     if (m_speechTask && m_recording) {
135         m_speechTask->stop();
136         speechTaskFired();
137     }
138 }
139 
speechTaskFired()140 void MockWebSpeechInputController::speechTaskFired()
141 {
142     if (m_recording) {
143         m_recording = false;
144         m_listener->didCompleteRecording(m_requestId);
145 
146         m_speechTask = new SpeechTask(this);
147         m_delegate->postTask(m_speechTask);
148     } else {
149         bool noResultsFound = false;
150         // We take a copy of the requestId here so that if scripts destroyed the input element
151         // inside one of the callbacks below, we'll still know what this session's requestId was.
152         int requestId = m_requestId;
153         m_requestId = 0;
154 
155         if (m_dumpRect) {
156             m_listener->setRecognitionResult(requestId, makeRectResult(m_requestRect));
157         } else if (m_language.empty()) {
158             // Empty language case must be handled separately to avoid problems with HashMap and empty keys.
159             if (!m_resultsForEmptyLanguage.empty())
160                 m_listener->setRecognitionResult(requestId, m_resultsForEmptyLanguage);
161             else
162                 noResultsFound = true;
163         } else {
164             if (m_recognitionResults.find(m_language) != m_recognitionResults.end())
165                 m_listener->setRecognitionResult(requestId, m_recognitionResults[m_language]);
166             else
167                 noResultsFound = true;
168         }
169 
170         if (noResultsFound) {
171             // Can't avoid setting a result even if no result was set for the given language.
172             // This would avoid generating the events used to check the results and the test would timeout.
173             string error("error: no result found for language '");
174             error.append(m_language);
175             error.append("'");
176 
177             WebSpeechInputResult res;
178             res.assign(WebString::fromUTF8(error), 1.0);
179 
180             vector<WebSpeechInputResult> results;
181             results.push_back(res);
182 
183             m_listener->setRecognitionResult(requestId, results);
184         }
185     }
186 }
187 
SpeechTask(MockWebSpeechInputController * mock)188 MockWebSpeechInputController::SpeechTask::SpeechTask(MockWebSpeechInputController* mock)
189     : WebMethodTask<MockWebSpeechInputController>::WebMethodTask(mock)
190 {
191 }
192 
stop()193 void MockWebSpeechInputController::SpeechTask::stop()
194 {
195     m_object->m_speechTask = 0;
196     cancel();
197 }
198 
runIfValid()199 void MockWebSpeechInputController::SpeechTask::runIfValid()
200 {
201     m_object->m_speechTask = 0;
202     m_object->speechTaskFired();
203 }
204 
205 }
206 
207 #endif
208