| 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 |