OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <queue> | 5 #include <queue> |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/safe_numerics.h" | 9 #include "base/safe_numerics.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 105 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
106 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 106 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
107 | 107 |
108 // Simulate a protobuf message streamed from the server containing a single | 108 // Simulate a protobuf message streamed from the server containing a single |
109 // result with two hypotheses. | 109 // result with two hypotheses. |
110 SpeechRecognitionResults results; | 110 SpeechRecognitionResults results; |
111 results.push_back(SpeechRecognitionResult()); | 111 results.push_back(SpeechRecognitionResult()); |
112 SpeechRecognitionResult& result = results.back(); | 112 SpeechRecognitionResult& result = results.back(); |
113 result.is_provisional = false; | 113 result.is_provisional = false; |
114 result.hypotheses.push_back( | 114 result.hypotheses.push_back( |
115 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis 1"), 0.1F)); | 115 SpeechRecognitionHypothesis(base::UTF8ToUTF16("hypothesis 1"), 0.1F)); |
116 result.hypotheses.push_back( | 116 result.hypotheses.push_back( |
117 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis 2"), 0.2F)); | 117 SpeechRecognitionHypothesis(base::UTF8ToUTF16("hypothesis 2"), 0.2F)); |
118 | 118 |
119 ProvideMockResultDownstream(result); | 119 ProvideMockResultDownstream(result); |
120 ExpectResultsReceived(results); | 120 ExpectResultsReceived(results); |
121 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 121 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
122 | 122 |
123 // Ensure everything is closed cleanly after the downstream is closed. | 123 // Ensure everything is closed cleanly after the downstream is closed. |
124 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); | 124 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); |
125 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); | 125 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); |
126 EndMockRecognition(); | 126 EndMockRecognition(); |
127 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); | 127 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); |
128 ASSERT_EQ(0U, results_.size()); | 128 ASSERT_EQ(0U, results_.size()); |
129 } | 129 } |
130 | 130 |
131 TEST_F(GoogleStreamingRemoteEngineTest, SeveralStreamingResults) { | 131 TEST_F(GoogleStreamingRemoteEngineTest, SeveralStreamingResults) { |
132 StartMockRecognition(); | 132 StartMockRecognition(); |
133 ASSERT_TRUE(GetUpstreamFetcher()); | 133 ASSERT_TRUE(GetUpstreamFetcher()); |
134 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); | 134 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); |
135 | 135 |
136 for (int i = 0; i < 4; ++i) { | 136 for (int i = 0; i < 4; ++i) { |
137 InjectDummyAudioChunk(); | 137 InjectDummyAudioChunk(); |
138 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 138 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
139 | 139 |
140 SpeechRecognitionResults results; | 140 SpeechRecognitionResults results; |
141 results.push_back(SpeechRecognitionResult()); | 141 results.push_back(SpeechRecognitionResult()); |
142 SpeechRecognitionResult& result = results.back(); | 142 SpeechRecognitionResult& result = results.back(); |
143 result.is_provisional = (i % 2 == 0); // Alternate result types. | 143 result.is_provisional = (i % 2 == 0); // Alternate result types. |
144 float confidence = result.is_provisional ? 0.0F : (i * 0.1F); | 144 float confidence = result.is_provisional ? 0.0F : (i * 0.1F); |
145 result.hypotheses.push_back( | 145 result.hypotheses.push_back(SpeechRecognitionHypothesis( |
146 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis"), confidence)); | 146 base::UTF8ToUTF16("hypothesis"), confidence)); |
147 | 147 |
148 ProvideMockResultDownstream(result); | 148 ProvideMockResultDownstream(result); |
149 ExpectResultsReceived(results); | 149 ExpectResultsReceived(results); |
150 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 150 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
151 } | 151 } |
152 | 152 |
153 // Ensure that a final (empty) audio chunk is uploaded on chunks end. | 153 // Ensure that a final (empty) audio chunk is uploaded on chunks end. |
154 engine_under_test_->AudioChunksEnded(); | 154 engine_under_test_->AudioChunksEnded(); |
155 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 155 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
156 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 156 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
157 | 157 |
158 // Simulate a final definitive result. | 158 // Simulate a final definitive result. |
159 SpeechRecognitionResults results; | 159 SpeechRecognitionResults results; |
160 results.push_back(SpeechRecognitionResult()); | 160 results.push_back(SpeechRecognitionResult()); |
161 SpeechRecognitionResult& result = results.back(); | 161 SpeechRecognitionResult& result = results.back(); |
162 result.is_provisional = false; | 162 result.is_provisional = false; |
163 result.hypotheses.push_back( | 163 result.hypotheses.push_back( |
164 SpeechRecognitionHypothesis(UTF8ToUTF16("The final result"), 1.0F)); | 164 SpeechRecognitionHypothesis(base::UTF8ToUTF16("The final result"), 1.0F)); |
165 ProvideMockResultDownstream(result); | 165 ProvideMockResultDownstream(result); |
166 ExpectResultsReceived(results); | 166 ExpectResultsReceived(results); |
167 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 167 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
168 | 168 |
169 // Ensure everything is closed cleanly after the downstream is closed. | 169 // Ensure everything is closed cleanly after the downstream is closed. |
170 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); | 170 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); |
171 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); | 171 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); |
172 EndMockRecognition(); | 172 EndMockRecognition(); |
173 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); | 173 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); |
174 ASSERT_EQ(0U, results_.size()); | 174 ASSERT_EQ(0U, results_.size()); |
175 } | 175 } |
176 | 176 |
177 TEST_F(GoogleStreamingRemoteEngineTest, NoFinalResultAfterAudioChunksEnded) { | 177 TEST_F(GoogleStreamingRemoteEngineTest, NoFinalResultAfterAudioChunksEnded) { |
178 StartMockRecognition(); | 178 StartMockRecognition(); |
179 ASSERT_TRUE(GetUpstreamFetcher()); | 179 ASSERT_TRUE(GetUpstreamFetcher()); |
180 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); | 180 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); |
181 | 181 |
182 // Simulate one pushed audio chunk. | 182 // Simulate one pushed audio chunk. |
183 InjectDummyAudioChunk(); | 183 InjectDummyAudioChunk(); |
184 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 184 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
185 | 185 |
186 // Simulate the corresponding definitive result. | 186 // Simulate the corresponding definitive result. |
187 SpeechRecognitionResults results; | 187 SpeechRecognitionResults results; |
188 results.push_back(SpeechRecognitionResult()); | 188 results.push_back(SpeechRecognitionResult()); |
189 SpeechRecognitionResult& result = results.back(); | 189 SpeechRecognitionResult& result = results.back(); |
190 result.hypotheses.push_back( | 190 result.hypotheses.push_back( |
191 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis"), 1.0F)); | 191 SpeechRecognitionHypothesis(base::UTF8ToUTF16("hypothesis"), 1.0F)); |
192 ProvideMockResultDownstream(result); | 192 ProvideMockResultDownstream(result); |
193 ExpectResultsReceived(results); | 193 ExpectResultsReceived(results); |
194 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 194 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
195 | 195 |
196 // Simulate a silent downstream closure after |AudioChunksEnded|. | 196 // Simulate a silent downstream closure after |AudioChunksEnded|. |
197 engine_under_test_->AudioChunksEnded(); | 197 engine_under_test_->AudioChunksEnded(); |
198 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 198 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
199 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 199 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
200 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); | 200 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); |
201 | 201 |
(...skipping 19 matching lines...) Expand all Loading... |
221 engine_under_test_->AudioChunksEnded(); | 221 engine_under_test_->AudioChunksEnded(); |
222 ASSERT_EQ(4U, UpstreamChunksUploadedFromLastCall()); | 222 ASSERT_EQ(4U, UpstreamChunksUploadedFromLastCall()); |
223 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 223 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
224 | 224 |
225 // Simulate only a provisional result. | 225 // Simulate only a provisional result. |
226 SpeechRecognitionResults results; | 226 SpeechRecognitionResults results; |
227 results.push_back(SpeechRecognitionResult()); | 227 results.push_back(SpeechRecognitionResult()); |
228 SpeechRecognitionResult& result = results.back(); | 228 SpeechRecognitionResult& result = results.back(); |
229 result.is_provisional = true; | 229 result.is_provisional = true; |
230 result.hypotheses.push_back( | 230 result.hypotheses.push_back( |
231 SpeechRecognitionHypothesis(UTF8ToUTF16("The final result"), 0.0F)); | 231 SpeechRecognitionHypothesis(base::UTF8ToUTF16("The final result"), 0.0F)); |
232 ProvideMockResultDownstream(result); | 232 ProvideMockResultDownstream(result); |
233 ExpectResultsReceived(results); | 233 ExpectResultsReceived(results); |
234 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 234 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
235 | 235 |
236 CloseMockDownstream(DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH); | 236 CloseMockDownstream(DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH); |
237 | 237 |
238 // Expect an empty result. | 238 // Expect an empty result. |
239 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); | 239 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); |
240 EndMockRecognition(); | 240 EndMockRecognition(); |
241 SpeechRecognitionResults empty_result; | 241 SpeechRecognitionResults empty_result; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 proto_result->add_alternative(); | 298 proto_result->add_alternative(); |
299 proto_alternative->set_transcript("foo"); | 299 proto_alternative->set_transcript("foo"); |
300 ProvideMockProtoResultDownstream(proto_event); | 300 ProvideMockProtoResultDownstream(proto_event); |
301 | 301 |
302 // Set up expectations. | 302 // Set up expectations. |
303 SpeechRecognitionResults results; | 303 SpeechRecognitionResults results; |
304 results.push_back(SpeechRecognitionResult()); | 304 results.push_back(SpeechRecognitionResult()); |
305 SpeechRecognitionResult& result = results.back(); | 305 SpeechRecognitionResult& result = results.back(); |
306 result.is_provisional = true; | 306 result.is_provisional = true; |
307 result.hypotheses.push_back( | 307 result.hypotheses.push_back( |
308 SpeechRecognitionHypothesis(UTF8ToUTF16("foo"), 0.5)); | 308 SpeechRecognitionHypothesis(base::UTF8ToUTF16("foo"), 0.5)); |
309 | 309 |
310 // Check that the protobuf generated the expected result. | 310 // Check that the protobuf generated the expected result. |
311 ExpectResultsReceived(results); | 311 ExpectResultsReceived(results); |
312 | 312 |
313 // Since it was a provisional result, recognition is still pending. | 313 // Since it was a provisional result, recognition is still pending. |
314 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 314 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
315 | 315 |
316 // Shut down. | 316 // Shut down. |
317 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); | 317 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); |
318 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); | 318 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 const SpeechRecognitionResult& result) { | 418 const SpeechRecognitionResult& result) { |
419 proto::SpeechRecognitionEvent proto_event; | 419 proto::SpeechRecognitionEvent proto_event; |
420 proto_event.set_status(proto::SpeechRecognitionEvent::STATUS_SUCCESS); | 420 proto_event.set_status(proto::SpeechRecognitionEvent::STATUS_SUCCESS); |
421 proto::SpeechRecognitionResult* proto_result = proto_event.add_result(); | 421 proto::SpeechRecognitionResult* proto_result = proto_event.add_result(); |
422 proto_result->set_final(!result.is_provisional); | 422 proto_result->set_final(!result.is_provisional); |
423 for (size_t i = 0; i < result.hypotheses.size(); ++i) { | 423 for (size_t i = 0; i < result.hypotheses.size(); ++i) { |
424 proto::SpeechRecognitionAlternative* proto_alternative = | 424 proto::SpeechRecognitionAlternative* proto_alternative = |
425 proto_result->add_alternative(); | 425 proto_result->add_alternative(); |
426 const SpeechRecognitionHypothesis& hypothesis = result.hypotheses[i]; | 426 const SpeechRecognitionHypothesis& hypothesis = result.hypotheses[i]; |
427 proto_alternative->set_confidence(hypothesis.confidence); | 427 proto_alternative->set_confidence(hypothesis.confidence); |
428 proto_alternative->set_transcript(UTF16ToUTF8(hypothesis.utterance)); | 428 proto_alternative->set_transcript(base::UTF16ToUTF8(hypothesis.utterance)); |
429 } | 429 } |
430 ProvideMockProtoResultDownstream(proto_event); | 430 ProvideMockProtoResultDownstream(proto_event); |
431 } | 431 } |
432 | 432 |
433 void GoogleStreamingRemoteEngineTest::CloseMockDownstream( | 433 void GoogleStreamingRemoteEngineTest::CloseMockDownstream( |
434 DownstreamError error) { | 434 DownstreamError error) { |
435 TestURLFetcher* downstream_fetcher = GetDownstreamFetcher(); | 435 TestURLFetcher* downstream_fetcher = GetDownstreamFetcher(); |
436 ASSERT_TRUE(downstream_fetcher); | 436 ASSERT_TRUE(downstream_fetcher); |
437 | 437 |
438 const URLRequestStatus::Status fetcher_status = | 438 const URLRequestStatus::Status fetcher_status = |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 | 490 |
491 // Prepend 4 byte prefix length indication to the protobuf message as | 491 // Prepend 4 byte prefix length indication to the protobuf message as |
492 // envisaged by the google streaming recognition webservice protocol. | 492 // envisaged by the google streaming recognition webservice protocol. |
493 uint32 prefix = HostToNet32(checked_numeric_cast<uint32>(msg_string.size())); | 493 uint32 prefix = HostToNet32(checked_numeric_cast<uint32>(msg_string.size())); |
494 msg_string.insert(0, reinterpret_cast<char*>(&prefix), sizeof(prefix)); | 494 msg_string.insert(0, reinterpret_cast<char*>(&prefix), sizeof(prefix)); |
495 | 495 |
496 return msg_string; | 496 return msg_string; |
497 } | 497 } |
498 | 498 |
499 } // namespace content | 499 } // namespace content |
OLD | NEW |