summaryrefslogtreecommitdiff
path: root/chromium/content/browser/speech
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/speech')
-rw-r--r--chromium/content/browser/speech/OWNERS2
-rw-r--r--chromium/content/browser/speech/audio_buffer.cc17
-rw-r--r--chromium/content/browser/speech/audio_buffer.h13
-rw-r--r--chromium/content/browser/speech/audio_encoder.cc2
-rw-r--r--chromium/content/browser/speech/chunked_byte_buffer.cc4
-rw-r--r--chromium/content/browser/speech/endpointer/endpointer_unittest.cc2
-rw-r--r--chromium/content/browser/speech/google_one_shot_remote_engine.cc28
-rw-r--r--chromium/content/browser/speech/google_streaming_remote_engine.cc98
-rw-r--r--chromium/content/browser/speech/google_streaming_remote_engine.h13
-rw-r--r--chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc73
-rw-r--r--chromium/content/browser/speech/speech_recognition_browsertest.cc11
-rw-r--r--chromium/content/browser/speech/speech_recognition_engine.h4
-rw-r--r--chromium/content/browser/speech/speech_recognition_manager_impl.cc51
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl.cc48
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_android.cc28
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_android.h12
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_unittest.cc4
17 files changed, 276 insertions, 134 deletions
diff --git a/chromium/content/browser/speech/OWNERS b/chromium/content/browser/speech/OWNERS
index b38caa6f1ff..1dede2088d2 100644
--- a/chromium/content/browser/speech/OWNERS
+++ b/chromium/content/browser/speech/OWNERS
@@ -1,3 +1 @@
-hans@chromium.org
tommi@chromium.org
-xians@chromium.org
diff --git a/chromium/content/browser/speech/audio_buffer.cc b/chromium/content/browser/speech/audio_buffer.cc
index 3e7d2a4a68e..823fff5291f 100644
--- a/chromium/content/browser/speech/audio_buffer.cc
+++ b/chromium/content/browser/speech/audio_buffer.cc
@@ -5,7 +5,6 @@
#include "content/browser/speech/audio_buffer.h"
#include "base/logging.h"
-#include "base/stl_util.h"
namespace content {
@@ -13,6 +12,11 @@ AudioChunk::AudioChunk(int bytes_per_sample)
: bytes_per_sample_(bytes_per_sample) {
}
+AudioChunk::AudioChunk(size_t length, int bytes_per_sample)
+ : data_string_(length, '\0'), bytes_per_sample_(bytes_per_sample) {
+ DCHECK_EQ(length % bytes_per_sample, 0U);
+}
+
AudioChunk::AudioChunk(const uint8* data, size_t length, int bytes_per_sample)
: data_string_(reinterpret_cast<const char*>(data), length),
bytes_per_sample_(bytes_per_sample) {
@@ -40,7 +44,6 @@ const int16* AudioChunk::SamplesData16() const {
return reinterpret_cast<const int16*>(data_string_.data());
}
-
AudioBuffer::AudioBuffer(int bytes_per_sample)
: bytes_per_sample_(bytes_per_sample) {
DCHECK(bytes_per_sample == 1 ||
@@ -64,17 +67,19 @@ scoped_refptr<AudioChunk> AudioBuffer::DequeueSingleChunk() {
}
scoped_refptr<AudioChunk> AudioBuffer::DequeueAll() {
- scoped_refptr<AudioChunk> chunk(new AudioChunk(bytes_per_sample_));
size_t resulting_length = 0;
ChunksContainer::const_iterator it;
// In order to improve performance, calulate in advance the total length
// and then copy the chunks.
for (it = chunks_.begin(); it != chunks_.end(); ++it) {
- resulting_length += (*it)->data_string_.length();
+ resulting_length += (*it)->AsString().length();
}
- chunk->data_string_.reserve(resulting_length);
+ scoped_refptr<AudioChunk> chunk(
+ new AudioChunk(resulting_length, bytes_per_sample_));
+ uint8* dest = chunk->writable_data();
for (it = chunks_.begin(); it != chunks_.end(); ++it) {
- chunk->data_string_.append((*it)->data_string_);
+ memcpy(dest, (*it)->AsString().data(), (*it)->AsString().length());
+ dest += (*it)->AsString().length();
}
Clear();
return chunk;
diff --git a/chromium/content/browser/speech/audio_buffer.h b/chromium/content/browser/speech/audio_buffer.h
index 783ae6679f3..7b0fd7e19df 100644
--- a/chromium/content/browser/speech/audio_buffer.h
+++ b/chromium/content/browser/speech/audio_buffer.h
@@ -19,6 +19,8 @@ class CONTENT_EXPORT AudioChunk :
public base::RefCountedThreadSafe<AudioChunk> {
public:
explicit AudioChunk(int bytes_per_sample);
+ // Creates a chunk of |length| bytes, initialized to zeros.
+ AudioChunk(size_t length, int bytes_per_sample);
AudioChunk(const uint8* data, size_t length, int bytes_per_sample);
bool IsEmpty() const;
@@ -27,14 +29,14 @@ class CONTENT_EXPORT AudioChunk :
const std::string& AsString() const;
int16 GetSample16(size_t index) const;
const int16* SamplesData16() const;
- friend class AudioBuffer;
+ uint8* writable_data() { return reinterpret_cast<uint8*>(&data_string_[0]); }
private:
- ~AudioChunk() {}
friend class base::RefCountedThreadSafe<AudioChunk>;
+ ~AudioChunk() {}
std::string data_string_;
- int bytes_per_sample_;
+ const int bytes_per_sample_;
DISALLOW_COPY_AND_ASSIGN(AudioChunk);
};
@@ -51,7 +53,8 @@ class AudioBuffer {
// Dequeues, in FIFO order, a single chunk respecting the length of the
// corresponding Enqueue call (in a nutshell: multiple Enqueue calls followed
- // by Dequeue calls will return the individual chunks without merging them).
+ // by DequeueSingleChunk calls will return the individual chunks without
+ // merging them).
scoped_refptr<AudioChunk> DequeueSingleChunk();
// Dequeues all previously enqueued chunks, merging them in a single chunk.
@@ -66,7 +69,7 @@ class AudioBuffer {
private:
typedef std::deque<scoped_refptr<AudioChunk> > ChunksContainer;
ChunksContainer chunks_;
- int bytes_per_sample_;
+ const int bytes_per_sample_;
DISALLOW_COPY_AND_ASSIGN(AudioBuffer);
};
diff --git a/chromium/content/browser/speech/audio_encoder.cc b/chromium/content/browser/speech/audio_encoder.cc
index 09b5dca287d..e145ddaba40 100644
--- a/chromium/content/browser/speech/audio_encoder.cc
+++ b/chromium/content/browser/speech/audio_encoder.cc
@@ -108,7 +108,7 @@ const int kMaxSpeexFrameLength = 110; // (44kbps rate sampled at 32kHz).
// Since the frame length gets written out as a byte in the encoded packet,
// make sure it is within the byte range.
-COMPILE_ASSERT(kMaxSpeexFrameLength <= 0xFF, invalidLength);
+static_assert(kMaxSpeexFrameLength <= 0xFF, "invalid length");
class SpeexEncoder : public AudioEncoder {
public:
diff --git a/chromium/content/browser/speech/chunked_byte_buffer.cc b/chromium/content/browser/speech/chunked_byte_buffer.cc
index ae8a6ce8245..5fcf5d18fe6 100644
--- a/chromium/content/browser/speech/chunked_byte_buffer.cc
+++ b/chromium/content/browser/speech/chunked_byte_buffer.cc
@@ -14,8 +14,8 @@ namespace {
static const size_t kHeaderLength = sizeof(uint32);
-COMPILE_ASSERT(sizeof(size_t) >= kHeaderLength,
- ChunkedByteBufferNotSupportedOnThisArchitecture);
+static_assert(sizeof(size_t) >= kHeaderLength,
+ "chunked byte buffer not supported on this architecture");
uint32 ReadBigEndian32(const uint8* buffer) {
return (static_cast<uint32>(buffer[3])) |
diff --git a/chromium/content/browser/speech/endpointer/endpointer_unittest.cc b/chromium/content/browser/speech/endpointer/endpointer_unittest.cc
index 807b6f68287..c65a7c9b4e1 100644
--- a/chromium/content/browser/speech/endpointer/endpointer_unittest.cc
+++ b/chromium/content/browser/speech/endpointer/endpointer_unittest.cc
@@ -13,7 +13,7 @@ const int kSampleRate = 8000; // 8 k samples per second for AMR encoding.
// At 8 sample per second a 20 ms frame is 160 samples, which corrsponds
// to the AMR codec.
const int kFrameSize = kSampleRate / kFrameRate; // 160 samples.
-COMPILE_ASSERT(kFrameSize == 160, invalid_frame_size);
+static_assert(kFrameSize == 160, "invalid frame size");
}
namespace content {
diff --git a/chromium/content/browser/speech/google_one_shot_remote_engine.cc b/chromium/content/browser/speech/google_one_shot_remote_engine.cc
index e52e713deb5..77f5c2cb6f6 100644
--- a/chromium/content/browser/speech/google_one_shot_remote_engine.cc
+++ b/chromium/content/browser/speech/google_one_shot_remote_engine.cc
@@ -55,7 +55,7 @@ bool ParseServerResponse(const std::string& response_body,
}
if (!response_value->IsType(base::Value::TYPE_DICTIONARY)) {
- VLOG(1) << "ParseServerResponse: Unexpected response type "
+ DVLOG(1) << "ParseServerResponse: Unexpected response type "
<< response_value->GetType();
return false;
}
@@ -65,7 +65,7 @@ bool ParseServerResponse(const std::string& response_body,
// Get the status.
int status;
if (!response_object->GetInteger(kStatusString, &status)) {
- VLOG(1) << "ParseServerResponse: " << kStatusString
+ DVLOG(1) << "ParseServerResponse: " << kStatusString
<< " is not a valid integer value.";
return false;
}
@@ -83,21 +83,21 @@ bool ParseServerResponse(const std::string& response_body,
default:
error->code = SPEECH_RECOGNITION_ERROR_NETWORK;
// Other status codes should not be returned by the server.
- VLOG(1) << "ParseServerResponse: unexpected status code " << status;
+ DVLOG(1) << "ParseServerResponse: unexpected status code " << status;
return false;
}
// Get the hypotheses.
const base::Value* hypotheses_value = NULL;
if (!response_object->Get(kHypothesesString, &hypotheses_value)) {
- VLOG(1) << "ParseServerResponse: Missing hypotheses attribute.";
+ DVLOG(1) << "ParseServerResponse: Missing hypotheses attribute.";
return false;
}
DCHECK(hypotheses_value);
if (!hypotheses_value->IsType(base::Value::TYPE_LIST)) {
- VLOG(1) << "ParseServerResponse: Unexpected hypotheses type "
- << hypotheses_value->GetType();
+ DVLOG(1) << "ParseServerResponse: Unexpected hypotheses type "
+ << hypotheses_value->GetType();
return false;
}
@@ -210,10 +210,8 @@ void GoogleOneShotRemoteEngine::StartRecognition() {
config_.audio_sample_rate,
config_.audio_num_bits_per_sample));
DCHECK(encoder_.get());
- url_fetcher_.reset(net::URLFetcher::Create(url_fetcher_id_for_tests,
- url,
- net::URLFetcher::POST,
- this));
+ url_fetcher_ = net::URLFetcher::Create(url_fetcher_id_for_tests, url,
+ net::URLFetcher::POST, this);
url_fetcher_->SetChunkedUpload(encoder_->mime_type());
url_fetcher_->SetRequestContext(url_context_.get());
url_fetcher_->SetReferrer(config_.origin_url);
@@ -247,12 +245,10 @@ void GoogleOneShotRemoteEngine::AudioChunksEnded() {
// UploadAudioChunk requires a non-empty final buffer. So we encode a packet
// of silence in case encoder had no data already.
- std::vector<int16> samples(
- config_.audio_sample_rate * kAudioPacketIntervalMs / 1000);
- scoped_refptr<AudioChunk> dummy_chunk(
- new AudioChunk(reinterpret_cast<uint8*>(&samples[0]),
- samples.size() * sizeof(int16),
- encoder_->bits_per_sample() / 8));
+ size_t sample_count =
+ config_.audio_sample_rate * kAudioPacketIntervalMs / 1000;
+ scoped_refptr<AudioChunk> dummy_chunk(new AudioChunk(
+ sample_count * sizeof(int16), encoder_->bits_per_sample() / 8));
encoder_->Encode(*dummy_chunk.get());
encoder_->Flush();
scoped_refptr<AudioChunk> encoded_dummy_data(
diff --git a/chromium/content/browser/speech/google_streaming_remote_engine.cc b/chromium/content/browser/speech/google_streaming_remote_engine.cc
index 7fea0fa90a6..fc8c6d24254 100644
--- a/chromium/content/browser/speech/google_streaming_remote_engine.cc
+++ b/chromium/content/browser/speech/google_streaming_remote_engine.cc
@@ -4,8 +4,10 @@
#include "content/browser/speech/google_streaming_remote_engine.h"
+#include <algorithm>
#include <vector>
+#include "base/big_endian.h"
#include "base/bind.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
@@ -81,6 +83,7 @@ GoogleStreamingRemoteEngine::GoogleStreamingRemoteEngine(
previous_response_length_(0),
got_last_definitive_result_(false),
is_dispatching_event_(false),
+ use_framed_post_data_(false),
state_(STATE_IDLE) {}
GoogleStreamingRemoteEngine::~GoogleStreamingRemoteEngine() {}
@@ -297,6 +300,18 @@ GoogleStreamingRemoteEngine::ConnectBothStreams(const FSMEventArgs&) {
DCHECK(encoder_.get());
const std::string request_key = GenerateRequestKey();
+ // Only use the framed post data format when a preamble needs to be logged.
+ use_framed_post_data_ = (config_.preamble &&
+ !config_.preamble->sample_data.empty() &&
+ !config_.auth_token.empty() &&
+ !config_.auth_scope.empty());
+ if (use_framed_post_data_) {
+ preamble_encoder_.reset(AudioEncoder::Create(
+ kDefaultAudioCodec,
+ config_.preamble->sample_rate,
+ config_.preamble->sample_depth * 8));
+ }
+
// Setup downstream fetcher.
std::vector<std::string> downstream_args;
downstream_args.push_back(
@@ -307,9 +322,8 @@ GoogleStreamingRemoteEngine::ConnectBothStreams(const FSMEventArgs&) {
std::string(kDownstreamUrl) +
JoinString(downstream_args, '&'));
- downstream_fetcher_.reset(URLFetcher::Create(
- kDownstreamUrlFetcherIdForTesting, downstream_url, URLFetcher::GET,
- this));
+ downstream_fetcher_ = URLFetcher::Create(
+ kDownstreamUrlFetcherIdForTesting, downstream_url, URLFetcher::GET, this);
downstream_fetcher_->SetRequestContext(url_context_.get());
downstream_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DO_NOT_SEND_COOKIES |
@@ -342,14 +356,30 @@ GoogleStreamingRemoteEngine::ConnectBothStreams(const FSMEventArgs&) {
upstream_args.push_back("continuous");
if (config_.interim_results)
upstream_args.push_back("interim");
-
+ if (!config_.auth_token.empty() && !config_.auth_scope.empty()) {
+ upstream_args.push_back(
+ "authScope=" + net::EscapeQueryParamValue(config_.auth_scope, true));
+ upstream_args.push_back(
+ "authToken=" + net::EscapeQueryParamValue(config_.auth_token, true));
+ }
+ if (use_framed_post_data_) {
+ std::string audio_format;
+ if (preamble_encoder_)
+ audio_format = preamble_encoder_->mime_type() + ",";
+ audio_format += encoder_->mime_type();
+ upstream_args.push_back(
+ "audioFormat=" + net::EscapeQueryParamValue(audio_format, true));
+ }
GURL upstream_url(std::string(kWebServiceBaseUrl) +
std::string(kUpstreamUrl) +
JoinString(upstream_args, '&'));
- upstream_fetcher_.reset(URLFetcher::Create(
- kUpstreamUrlFetcherIdForTesting, upstream_url, URLFetcher::POST, this));
- upstream_fetcher_->SetChunkedUpload(encoder_->mime_type());
+ upstream_fetcher_ = URLFetcher::Create(kUpstreamUrlFetcherIdForTesting,
+ upstream_url, URLFetcher::POST, this);
+ if (use_framed_post_data_)
+ upstream_fetcher_->SetChunkedUpload("application/octet-stream");
+ else
+ upstream_fetcher_->SetChunkedUpload(encoder_->mime_type());
upstream_fetcher_->SetRequestContext(url_context_.get());
upstream_fetcher_->SetReferrer(config_.origin_url);
upstream_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
@@ -357,6 +387,19 @@ GoogleStreamingRemoteEngine::ConnectBothStreams(const FSMEventArgs&) {
net::LOAD_DO_NOT_SEND_AUTH_DATA);
upstream_fetcher_->Start();
previous_response_length_ = 0;
+
+ if (preamble_encoder_) {
+ // Encode and send preamble right away.
+ scoped_refptr<AudioChunk> chunk = new AudioChunk(
+ reinterpret_cast<const uint8*>(config_.preamble->sample_data.data()),
+ config_.preamble->sample_data.size(),
+ config_.preamble->sample_depth);
+ preamble_encoder_->Encode(*chunk);
+ preamble_encoder_->Flush();
+ scoped_refptr<AudioChunk> encoded_data(
+ preamble_encoder_->GetEncodedDataAndClear());
+ UploadAudioChunk(encoded_data->AsString(), FRAME_PREAMBLE_AUDIO, false);
+ }
return STATE_BOTH_STREAMS_CONNECTED;
}
@@ -370,7 +413,7 @@ GoogleStreamingRemoteEngine::TransmitAudioUpstream(
DCHECK_EQ(audio.bytes_per_sample(), config_.audio_num_bits_per_sample / 8);
encoder_->Encode(audio);
scoped_refptr<AudioChunk> encoded_data(encoder_->GetEncodedDataAndClear());
- upstream_fetcher_->AppendChunkToUpload(encoded_data->AsString(), false);
+ UploadAudioChunk(encoded_data->AsString(), FRAME_RECOGNITION_AUDIO, false);
return state_;
}
@@ -401,20 +444,17 @@ GoogleStreamingRemoteEngine::ProcessDownstreamResponse(
case proto::SpeechRecognitionEvent::STATUS_ABORTED:
return Abort(SPEECH_RECOGNITION_ERROR_ABORTED);
case proto::SpeechRecognitionEvent::STATUS_AUDIO_CAPTURE:
- return Abort(SPEECH_RECOGNITION_ERROR_AUDIO);
+ return Abort(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE);
case proto::SpeechRecognitionEvent::STATUS_NETWORK:
return Abort(SPEECH_RECOGNITION_ERROR_NETWORK);
case proto::SpeechRecognitionEvent::STATUS_NOT_ALLOWED:
- // TODO(hans): We need a better error code for this.
- return Abort(SPEECH_RECOGNITION_ERROR_ABORTED);
+ return Abort(SPEECH_RECOGNITION_ERROR_NOT_ALLOWED);
case proto::SpeechRecognitionEvent::STATUS_SERVICE_NOT_ALLOWED:
- // TODO(hans): We need a better error code for this.
- return Abort(SPEECH_RECOGNITION_ERROR_ABORTED);
+ return Abort(SPEECH_RECOGNITION_ERROR_SERVICE_NOT_ALLOWED);
case proto::SpeechRecognitionEvent::STATUS_BAD_GRAMMAR:
return Abort(SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR);
case proto::SpeechRecognitionEvent::STATUS_LANGUAGE_NOT_SUPPORTED:
- // TODO(hans): We need a better error code for this.
- return Abort(SPEECH_RECOGNITION_ERROR_ABORTED);
+ return Abort(SPEECH_RECOGNITION_ERROR_LANGUAGE_NOT_SUPPORTED);
}
}
@@ -471,12 +511,10 @@ GoogleStreamingRemoteEngine::CloseUpstreamAndWaitForResults(
// The encoder requires a non-empty final buffer. So we encode a packet
// of silence in case encoder had no data already.
- std::vector<short> samples(
- config_.audio_sample_rate * kAudioPacketIntervalMs / 1000);
- scoped_refptr<AudioChunk> dummy_chunk =
- new AudioChunk(reinterpret_cast<uint8*>(&samples[0]),
- samples.size() * sizeof(short),
- encoder_->bits_per_sample() / 8);
+ size_t sample_count =
+ config_.audio_sample_rate * kAudioPacketIntervalMs / 1000;
+ scoped_refptr<AudioChunk> dummy_chunk = new AudioChunk(
+ sample_count * sizeof(int16), encoder_->bits_per_sample() / 8);
encoder_->Encode(*dummy_chunk.get());
encoder_->Flush();
scoped_refptr<AudioChunk> encoded_dummy_data =
@@ -484,7 +522,9 @@ GoogleStreamingRemoteEngine::CloseUpstreamAndWaitForResults(
DCHECK(!encoded_dummy_data->IsEmpty());
encoder_.reset();
- upstream_fetcher_->AppendChunkToUpload(encoded_dummy_data->AsString(), true);
+ UploadAudioChunk(encoded_dummy_data->AsString(),
+ FRAME_RECOGNITION_AUDIO,
+ true);
got_last_definitive_result_ = false;
return STATE_WAITING_DOWNSTREAM_RESULTS;
}
@@ -572,6 +612,20 @@ std::string GoogleStreamingRemoteEngine::GenerateRequestKey() const {
return base::HexEncode(reinterpret_cast<void*>(&key), sizeof(key));
}
+void GoogleStreamingRemoteEngine::UploadAudioChunk(const std::string& data,
+ FrameType type,
+ bool is_final) {
+ if (use_framed_post_data_) {
+ std::string frame(data.size() + 8, 0);
+ base::WriteBigEndian(&frame[0], static_cast<uint32_t>(data.size()));
+ base::WriteBigEndian(&frame[4], static_cast<uint32_t>(type));
+ frame.replace(8, data.size(), data);
+ upstream_fetcher_->AppendChunkToUpload(frame, is_final);
+ } else {
+ upstream_fetcher_->AppendChunkToUpload(data, is_final);
+ }
+}
+
GoogleStreamingRemoteEngine::FSMEventArgs::FSMEventArgs(FSMEvent event_value)
: event(event_value) {
}
diff --git a/chromium/content/browser/speech/google_streaming_remote_engine.h b/chromium/content/browser/speech/google_streaming_remote_engine.h
index 961ef0877db..15b866ba63b 100644
--- a/chromium/content/browser/speech/google_streaming_remote_engine.h
+++ b/chromium/content/browser/speech/google_streaming_remote_engine.h
@@ -79,6 +79,13 @@ class CONTENT_EXPORT GoogleStreamingRemoteEngine
static const int kWebserviceStatusNoError;
static const int kWebserviceStatusErrorNoMatch;
+ // Frame type for framed POST data. Do NOT change these. They must match
+ // values the server expects.
+ enum FrameType {
+ FRAME_PREAMBLE_AUDIO = 0,
+ FRAME_RECOGNITION_AUDIO = 1
+ };
+
// Data types for the internal Finite State Machine (FSM).
enum FSMState {
STATE_IDLE = 0,
@@ -143,15 +150,21 @@ class CONTENT_EXPORT GoogleStreamingRemoteEngine
std::string GetAcceptedLanguages() const;
std::string GenerateRequestKey() const;
+ // Upload a single chunk of audio data. Handles both unframed and framed
+ // upload formats, and uses the appropriate one.
+ void UploadAudioChunk(const std::string& data, FrameType type, bool is_final);
+
SpeechRecognitionEngineConfig config_;
scoped_ptr<net::URLFetcher> upstream_fetcher_;
scoped_ptr<net::URLFetcher> downstream_fetcher_;
scoped_refptr<net::URLRequestContextGetter> url_context_;
scoped_ptr<AudioEncoder> encoder_;
+ scoped_ptr<AudioEncoder> preamble_encoder_;
ChunkedByteBuffer chunked_byte_buffer_;
size_t previous_response_length_;
bool got_last_definitive_result_;
bool is_dispatching_event_;
+ bool use_framed_post_data_;
FSMState state_;
DISALLOW_COPY_AND_ASSIGN(GoogleStreamingRemoteEngine);
diff --git a/chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc b/chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc
index 57947e61e5d..c3d7ce5c4e1 100644
--- a/chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc
+++ b/chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc
@@ -4,6 +4,7 @@
#include <queue>
+#include "base/big_endian.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/numerics/safe_conversions.h"
@@ -27,6 +28,10 @@ using net::TestURLFetcherFactory;
namespace content {
+// Frame types for framed POST data.
+static const uint32_t kFrameTypePreamble = 0;
+static const uint32_t kFrameTypeRecognitionAudio = 1;
+
// Note: the terms upstream and downstream are from the point-of-view of the
// client (engine_under_test_).
@@ -73,10 +78,12 @@ class GoogleStreamingRemoteEngineTest : public SpeechRecognitionEngineDelegate,
void EndMockRecognition();
void InjectDummyAudioChunk();
size_t UpstreamChunksUploadedFromLastCall();
+ std::string LastUpstreamChunkUploaded();
void ProvideMockProtoResultDownstream(
const proto::SpeechRecognitionEvent& result);
void ProvideMockResultDownstream(const SpeechRecognitionResult& result);
void ExpectResultsReceived(const SpeechRecognitionResults& result);
+ void ExpectFramedChunk(const std::string& chunk, uint32_t type);
void CloseMockDownstream(DownstreamError error);
scoped_ptr<GoogleStreamingRemoteEngine> engine_under_test_;
@@ -325,6 +332,56 @@ TEST_F(GoogleStreamingRemoteEngineTest, Stability) {
ASSERT_EQ(0U, results_.size());
}
+TEST_F(GoogleStreamingRemoteEngineTest, SendPreamble) {
+ const size_t kPreambleLength = 100;
+ scoped_refptr<SpeechRecognitionSessionPreamble> preamble =
+ new SpeechRecognitionSessionPreamble();
+ preamble->sample_rate = 16000;
+ preamble->sample_depth = 2;
+ preamble->sample_data.assign(kPreambleLength, 0);
+ SpeechRecognitionEngine::Config config;
+ config.auth_token = "foo";
+ config.auth_scope = "bar";
+ config.preamble = preamble;
+ engine_under_test_->SetConfig(config);
+
+ StartMockRecognition();
+ ASSERT_TRUE(GetUpstreamFetcher());
+ // First chunk uploaded should be the preamble.
+ ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ std::string chunk = LastUpstreamChunkUploaded();
+ ExpectFramedChunk(chunk, kFrameTypePreamble);
+
+ for (int i = 0; i < 3; ++i) {
+ InjectDummyAudioChunk();
+ ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ chunk = LastUpstreamChunkUploaded();
+ ExpectFramedChunk(chunk, kFrameTypeRecognitionAudio);
+ }
+ engine_under_test_->AudioChunksEnded();
+ ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
+
+ // Simulate a protobuf message streamed from the server containing a single
+ // result with one hypotheses.
+ SpeechRecognitionResults results;
+ results.push_back(SpeechRecognitionResult());
+ SpeechRecognitionResult& result = results.back();
+ result.is_provisional = false;
+ result.hypotheses.push_back(
+ SpeechRecognitionHypothesis(base::UTF8ToUTF16("hypothesis 1"), 0.1F));
+
+ ProvideMockResultDownstream(result);
+ ExpectResultsReceived(results);
+ ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
+
+ // Ensure everything is closed cleanly after the downstream is closed.
+ CloseMockDownstream(DOWNSTREAM_ERROR_NONE);
+ ASSERT_FALSE(engine_under_test_->IsRecognitionPending());
+ EndMockRecognition();
+ ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ ASSERT_EQ(0U, results_.size());
+}
+
void GoogleStreamingRemoteEngineTest::SetUp() {
engine_under_test_.reset(
new GoogleStreamingRemoteEngine(NULL /*URLRequestContextGetter*/));
@@ -397,6 +454,13 @@ size_t GoogleStreamingRemoteEngineTest::UpstreamChunksUploadedFromLastCall() {
return new_chunks;
}
+std::string GoogleStreamingRemoteEngineTest::LastUpstreamChunkUploaded() {
+ TestURLFetcher* upstream_fetcher = GetUpstreamFetcher();
+ DCHECK(upstream_fetcher);
+ DCHECK(!upstream_fetcher->upload_chunks().empty());
+ return upstream_fetcher->upload_chunks().back();
+}
+
void GoogleStreamingRemoteEngineTest::ProvideMockProtoResultDownstream(
const proto::SpeechRecognitionEvent& result) {
TestURLFetcher* downstream_fetcher = GetDownstreamFetcher();
@@ -483,6 +547,15 @@ bool GoogleStreamingRemoteEngineTest::ResultsAreEqual(
return true;
}
+void GoogleStreamingRemoteEngineTest::ExpectFramedChunk(
+ const std::string& chunk, uint32_t type) {
+ uint32_t value;
+ base::ReadBigEndian(&chunk[0], &value);
+ EXPECT_EQ(chunk.size() - 8, value);
+ base::ReadBigEndian(&chunk[4], &value);
+ EXPECT_EQ(type, value);
+}
+
std::string GoogleStreamingRemoteEngineTest::SerializeProtobufResponse(
const proto::SpeechRecognitionEvent& msg) {
std::string msg_string;
diff --git a/chromium/content/browser/speech/speech_recognition_browsertest.cc b/chromium/content/browser/speech/speech_recognition_browsertest.cc
index 02671a4786f..8bc0749f40e 100644
--- a/chromium/content/browser/speech/speech_recognition_browsertest.cc
+++ b/chromium/content/browser/speech/speech_recognition_browsertest.cc
@@ -94,7 +94,7 @@ class SpeechRecognitionBrowserTest :
}
std::string GetPageFragment() {
- return shell()->web_contents()->GetURL().ref();
+ return shell()->web_contents()->GetLastCommittedURL().ref();
}
const StreamingServerState &streaming_server_state() {
@@ -188,13 +188,8 @@ class SpeechRecognitionBrowserTest :
// Simply loads the test page and checks if it was able to create a Speech
// Recognition object in JavaScript, to make sure the Web Speech API is enabled.
-// http://crbug.com/396414
-#if defined(OS_WIN) || defined(OS_MACOSX)
-#define MAYBE_Precheck DISABLED_Precheck
-#else
-#define MAYBE_Precheck Precheck
-#endif
-IN_PROC_BROWSER_TEST_F(SpeechRecognitionBrowserTest, MAYBE_Precheck) {
+// Flaky on all platforms. http://crbug.com/396414.
+IN_PROC_BROWSER_TEST_F(SpeechRecognitionBrowserTest, DISABLED_Precheck) {
NavigateToURLBlockUntilNavigationsComplete(
shell(), GetTestUrlFromFragment("precheck"), 2);
diff --git a/chromium/content/browser/speech/speech_recognition_engine.h b/chromium/content/browser/speech/speech_recognition_engine.h
index 73ba26ec7e5..4f945b510ec 100644
--- a/chromium/content/browser/speech/speech_recognition_engine.h
+++ b/chromium/content/browser/speech/speech_recognition_engine.h
@@ -9,6 +9,7 @@
#include "base/basictypes.h"
#include "content/common/content_export.h"
+#include "content/public/browser/speech_recognition_session_preamble.h"
#include "content/public/common/speech_recognition_grammar.h"
#include "content/public/common/speech_recognition_result.h"
@@ -59,6 +60,9 @@ class SpeechRecognitionEngine {
std::string origin_url;
int audio_sample_rate;
int audio_num_bits_per_sample;
+ std::string auth_token;
+ std::string auth_scope;
+ scoped_refptr<SpeechRecognitionSessionPreamble> preamble;
};
virtual ~SpeechRecognitionEngine() {}
diff --git a/chromium/content/browser/speech/speech_recognition_manager_impl.cc b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
index 1a054204c44..f02c29f1dd4 100644
--- a/chromium/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
@@ -39,7 +39,7 @@ namespace {
SpeechRecognitionManagerImpl* g_speech_recognition_manager_impl;
void ShowAudioInputSettingsOnFileThread(media::AudioManager* audio_manager) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
audio_manager->ShowAudioInputSettings();
}
@@ -69,7 +69,7 @@ SpeechRecognitionManagerImpl::SpeechRecognitionManagerImpl(
last_session_id_(kSessionIDInvalid),
is_dispatching_event_(false),
delegate_(GetContentClient()->browser()->
- GetSpeechRecognitionManagerDelegate()),
+ CreateSpeechRecognitionManagerDelegate()),
weak_factory_(this) {
DCHECK(!g_speech_recognition_manager_impl);
g_speech_recognition_manager_impl = this;
@@ -91,7 +91,7 @@ SpeechRecognitionManagerImpl::~SpeechRecognitionManagerImpl() {
int SpeechRecognitionManagerImpl::CreateSession(
const SpeechRecognitionSessionConfig& config) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
const int session_id = GetNextSessionID();
DCHECK(!SessionExists(session_id));
@@ -132,6 +132,9 @@ int SpeechRecognitionManagerImpl::CreateSession(
remote_engine_config.hardware_info = hardware_info;
remote_engine_config.origin_url =
can_report_metrics ? config.origin_url : std::string();
+ remote_engine_config.auth_token = config.auth_token;
+ remote_engine_config.auth_scope = config.auth_scope;
+ remote_engine_config.preamble = config.preamble;
SpeechRecognitionEngine* google_remote_engine;
if (config.is_legacy_api) {
@@ -157,7 +160,7 @@ int SpeechRecognitionManagerImpl::CreateSession(
}
void SpeechRecognitionManagerImpl::StartSession(int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -181,7 +184,7 @@ void SpeechRecognitionManagerImpl::StartSession(int session_id) {
void SpeechRecognitionManagerImpl::RecognitionAllowedCallback(int session_id,
bool ask_user,
bool is_allowed) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -229,7 +232,7 @@ void SpeechRecognitionManagerImpl::MediaRequestPermissionCallback(
int session_id,
const MediaStreamDevices& devices,
scoped_ptr<MediaStreamUIProxy> stream_ui) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
SessionsTable::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end())
@@ -252,7 +255,7 @@ void SpeechRecognitionManagerImpl::MediaRequestPermissionCallback(
}
void SpeechRecognitionManagerImpl::AbortSession(int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -273,7 +276,7 @@ void SpeechRecognitionManagerImpl::AbortSession(int session_id) {
}
void SpeechRecognitionManagerImpl::StopAudioCaptureForSession(int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -294,7 +297,7 @@ void SpeechRecognitionManagerImpl::StopAudioCaptureForSession(int session_id) {
// (if any).
void SpeechRecognitionManagerImpl::OnRecognitionStart(int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -313,7 +316,7 @@ void SpeechRecognitionManagerImpl::OnRecognitionStart(int session_id) {
}
void SpeechRecognitionManagerImpl::OnAudioStart(int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -326,7 +329,7 @@ void SpeechRecognitionManagerImpl::OnAudioStart(int session_id) {
void SpeechRecognitionManagerImpl::OnEnvironmentEstimationComplete(
int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -338,7 +341,7 @@ void SpeechRecognitionManagerImpl::OnEnvironmentEstimationComplete(
}
void SpeechRecognitionManagerImpl::OnSoundStart(int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -350,7 +353,7 @@ void SpeechRecognitionManagerImpl::OnSoundStart(int session_id) {
}
void SpeechRecognitionManagerImpl::OnSoundEnd(int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -361,7 +364,7 @@ void SpeechRecognitionManagerImpl::OnSoundEnd(int session_id) {
}
void SpeechRecognitionManagerImpl::OnAudioEnd(int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -379,7 +382,7 @@ void SpeechRecognitionManagerImpl::OnAudioEnd(int session_id) {
void SpeechRecognitionManagerImpl::OnRecognitionResults(
int session_id, const SpeechRecognitionResults& results) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -391,7 +394,7 @@ void SpeechRecognitionManagerImpl::OnRecognitionResults(
void SpeechRecognitionManagerImpl::OnRecognitionError(
int session_id, const SpeechRecognitionError& error) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -403,7 +406,7 @@ void SpeechRecognitionManagerImpl::OnRecognitionError(
void SpeechRecognitionManagerImpl::OnAudioLevelsChange(
int session_id, float volume, float noise_volume) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -414,7 +417,7 @@ void SpeechRecognitionManagerImpl::OnAudioLevelsChange(
}
void SpeechRecognitionManagerImpl::OnRecognitionEnd(int session_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -432,9 +435,9 @@ void SpeechRecognitionManagerImpl::OnRecognitionEnd(int session_id) {
int SpeechRecognitionManagerImpl::GetSession(
int render_process_id, int render_view_id, int request_id) const {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
SessionsTable::const_iterator iter;
- for(iter = sessions_.begin(); iter != sessions_.end(); ++iter) {
+ for (iter = sessions_.begin(); iter != sessions_.end(); ++iter) {
const int session_id = iter->first;
const SpeechRecognitionSessionContext& context = iter->second->context;
if (context.render_process_id == render_process_id &&
@@ -456,7 +459,7 @@ void SpeechRecognitionManagerImpl::AbortAllSessionsForRenderProcess(
// This method gracefully destroys sessions for the listener. However, since
// the listener itself is likely to be destroyed after this call, we avoid
// dispatching further events to it, marking the |listener_is_active| flag.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
for (SessionsTable::iterator it = sessions_.begin(); it != sessions_.end();
++it) {
Session* session = it->second;
@@ -470,7 +473,7 @@ void SpeechRecognitionManagerImpl::AbortAllSessionsForRenderProcess(
void SpeechRecognitionManagerImpl::AbortAllSessionsForRenderView(
int render_process_id,
int render_view_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
for (SessionsTable::iterator it = sessions_.begin(); it != sessions_.end();
++it) {
Session* session = it->second;
@@ -484,7 +487,7 @@ void SpeechRecognitionManagerImpl::AbortAllSessionsForRenderView(
// ----------------------- Core FSM implementation ---------------------------
void SpeechRecognitionManagerImpl::DispatchEvent(int session_id,
FSMEvent event) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
// There are some corner cases in which the session might be deleted (due to
// an EndRecognition event) between a request (e.g. Abort) and its dispatch.
@@ -648,7 +651,7 @@ bool SpeechRecognitionManagerImpl::SessionExists(int session_id) const {
SpeechRecognitionManagerImpl::Session*
SpeechRecognitionManagerImpl::GetSession(int session_id) const {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
SessionsTable::const_iterator iter = sessions_.find(session_id);
DCHECK(iter != sessions_.end());
return iter->second;
diff --git a/chromium/content/browser/speech/speech_recognizer_impl.cc b/chromium/content/browser/speech/speech_recognizer_impl.cc
index f6fb3900a5e..a08ffe17661 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl.cc
@@ -13,7 +13,6 @@
#include "content/browser/speech/google_one_shot_remote_engine.h"
#include "content/public/browser/speech_recognition_event_listener.h"
#include "media/base/audio_converter.h"
-#include "net/url_request/url_request_context_getter.h"
#if defined(OS_WIN)
#include "media/audio/win/core_audio_util_win.h"
@@ -56,7 +55,6 @@ class SpeechRecognizerImpl::OnDataConverter
const AudioParameters input_parameters_;
const AudioParameters output_parameters_;
bool waiting_for_input_;
- scoped_ptr<uint8[]> converted_data_;
DISALLOW_COPY_AND_ASSIGN(OnDataConverter);
};
@@ -108,20 +106,20 @@ const int SpeechRecognizerImpl::kNoSpeechTimeoutMs = 8000;
const int SpeechRecognizerImpl::kEndpointerEstimationTimeMs = 300;
media::AudioManager* SpeechRecognizerImpl::audio_manager_for_tests_ = NULL;
-COMPILE_ASSERT(SpeechRecognizerImpl::kNumBitsPerAudioSample % 8 == 0,
- kNumBitsPerAudioSample_must_be_a_multiple_of_8);
+static_assert(SpeechRecognizerImpl::kNumBitsPerAudioSample % 8 == 0,
+ "kNumBitsPerAudioSample must be a multiple of 8");
// SpeechRecognizerImpl::OnDataConverter implementation
SpeechRecognizerImpl::OnDataConverter::OnDataConverter(
- const AudioParameters& input_params, const AudioParameters& output_params)
+ const AudioParameters& input_params,
+ const AudioParameters& output_params)
: audio_converter_(input_params, output_params, false),
input_bus_(AudioBus::Create(input_params)),
output_bus_(AudioBus::Create(output_params)),
input_parameters_(input_params),
output_parameters_(output_params),
- waiting_for_input_(false),
- converted_data_(new uint8[output_parameters_.GetBytesPerBuffer()]) {
+ waiting_for_input_(false) {
audio_converter_.AddInput(this);
}
@@ -140,16 +138,13 @@ scoped_refptr<AudioChunk> SpeechRecognizerImpl::OnDataConverter::Convert(
waiting_for_input_ = true;
audio_converter_.Convert(output_bus_.get());
- output_bus_->ToInterleaved(
- output_bus_->frames(), output_parameters_.bits_per_sample() / 8,
- converted_data_.get());
-
- // TODO(primiano): Refactor AudioChunk to avoid the extra-copy here
- // (see http://crbug.com/249316 for details).
- return scoped_refptr<AudioChunk>(new AudioChunk(
- converted_data_.get(),
- output_parameters_.GetBytesPerBuffer(),
- output_parameters_.bits_per_sample() / 8));
+ scoped_refptr<AudioChunk> chunk(
+ new AudioChunk(output_parameters_.GetBytesPerBuffer(),
+ output_parameters_.bits_per_sample() / 8));
+ output_bus_->ToInterleaved(output_bus_->frames(),
+ output_parameters_.bits_per_sample() / 8,
+ chunk->writable_data());
+ return chunk;
}
double SpeechRecognizerImpl::OnDataConverter::ProvideInput(
@@ -236,12 +231,12 @@ void SpeechRecognizerImpl::StopAudioCapture() {
bool SpeechRecognizerImpl::IsActive() const {
// Checking the FSM state from another thread (thus, while the FSM is
// potentially concurrently evolving) is meaningless.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
return state_ != STATE_IDLE && state_ != STATE_ENDED;
}
bool SpeechRecognizerImpl::IsCapturingAudio() const {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // See IsActive().
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); // See IsActive().
const bool is_capturing_audio = state_ >= STATE_STARTING &&
state_ <= STATE_RECOGNIZING;
DCHECK((is_capturing_audio && (audio_controller_.get() != NULL)) ||
@@ -255,7 +250,7 @@ SpeechRecognizerImpl::recognition_engine() const {
}
SpeechRecognizerImpl::~SpeechRecognizerImpl() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
endpointer_.EndSession();
if (audio_controller_.get()) {
audio_controller_->Close(
@@ -317,7 +312,7 @@ void SpeechRecognizerImpl::OnSpeechRecognitionEngineError(
// does, but they will become flaky if TestAudioInputController will be fixed.
void SpeechRecognizerImpl::DispatchEvent(const FSMEventArgs& event_args) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_LE(event_args.event, EVENT_MAX_VALUE);
DCHECK_LE(state_, STATE_MAX_VALUE);
@@ -508,7 +503,7 @@ SpeechRecognizerImpl::StartRecording(const FSMEventArgs&) {
// TODO(xians): Check if the OS has the device with |device_id_|, return
// |SPEECH_AUDIO_ERROR_DETAILS_NO_MIC| if the target device does not exist.
if (!audio_manager->HasAudioInputDevices()) {
- return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO,
+ return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE,
SPEECH_AUDIO_ERROR_DETAILS_NO_MIC));
}
@@ -518,7 +513,8 @@ SpeechRecognizerImpl::StartRecording(const FSMEventArgs&) {
device_id_);
if (!in_params.IsValid() && !unit_test_is_active) {
DLOG(ERROR) << "Invalid native audio input parameters";
- return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO));
+ return Abort(
+ SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE));
}
// Audio converter shall provide audio based on these parameters as output.
@@ -569,7 +565,8 @@ SpeechRecognizerImpl::StartRecording(const FSMEventArgs&) {
audio_manager, this, input_parameters, device_id_, NULL);
if (!audio_controller_.get()) {
- return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO));
+ return Abort(
+ SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE));
}
audio_log_->OnCreated(0, input_parameters, device_id_);
@@ -654,7 +651,8 @@ SpeechRecognizerImpl::AbortSilently(const FSMEventArgs& event_args) {
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::AbortWithError(const FSMEventArgs& event_args) {
if (event_args.event == EVENT_AUDIO_ERROR) {
- return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO));
+ return Abort(
+ SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE));
} else if (event_args.event == EVENT_ENGINE_ERROR) {
return Abort(event_args.engine_error);
}
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_android.cc b/chromium/content/browser/speech/speech_recognizer_impl_android.cc
index 2e8c57e87b2..0a43def06b3 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_android.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl_android.cc
@@ -37,7 +37,7 @@ SpeechRecognizerImplAndroid::~SpeechRecognizerImplAndroid() { }
void SpeechRecognizerImplAndroid::StartRecognition(
const std::string& device_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(xians): Open the correct device for speech on Android.
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
&SpeechRecognitionEventListener::OnRecognitionStart,
@@ -52,7 +52,7 @@ void SpeechRecognizerImplAndroid::StartRecognition(
void SpeechRecognizerImplAndroid::StartRecognitionOnUIThread(
std::string language, bool continuous, bool interim_results) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
JNIEnv* env = AttachCurrentThread();
j_recognition_.Reset(Java_SpeechRecognition_createSpeechRecognition(env,
GetApplicationContext(), reinterpret_cast<intptr_t>(this)));
@@ -68,7 +68,7 @@ void SpeechRecognizerImplAndroid::AbortRecognition() {
&content::SpeechRecognizerImplAndroid::AbortRecognition, this));
return;
}
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
JNIEnv* env = AttachCurrentThread();
if (!j_recognition_.is_null())
Java_SpeechRecognition_abortRecognition(env, j_recognition_.obj());
@@ -80,19 +80,19 @@ void SpeechRecognizerImplAndroid::StopAudioCapture() {
&content::SpeechRecognizerImplAndroid::StopAudioCapture, this));
return;
}
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
JNIEnv* env = AttachCurrentThread();
if (!j_recognition_.is_null())
Java_SpeechRecognition_stopRecognition(env, j_recognition_.obj());
}
bool SpeechRecognizerImplAndroid::IsActive() const {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
return state_ != STATE_IDLE;
}
bool SpeechRecognizerImplAndroid::IsCapturingAudio() const {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
return state_ == STATE_CAPTURING_AUDIO;
}
@@ -103,7 +103,7 @@ void SpeechRecognizerImplAndroid::OnAudioStart(JNIEnv* env, jobject obj) {
static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
return;
}
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
state_ = STATE_CAPTURING_AUDIO;
listener()->OnAudioStart(session_id());
}
@@ -115,7 +115,7 @@ void SpeechRecognizerImplAndroid::OnSoundStart(JNIEnv* env, jobject obj) {
static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
return;
}
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
listener()->OnSoundStart(session_id());
}
@@ -126,7 +126,7 @@ void SpeechRecognizerImplAndroid::OnSoundEnd(JNIEnv* env, jobject obj) {
static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
return;
}
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
listener()->OnSoundEnd(session_id());
}
@@ -137,7 +137,7 @@ void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env, jobject obj) {
static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
return;
}
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (state_ == STATE_CAPTURING_AUDIO)
state_ = STATE_AWAITING_FINAL_RESULT;
listener()->OnAudioEnd(session_id());
@@ -145,7 +145,7 @@ void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env, jobject obj) {
void SpeechRecognizerImplAndroid::OnRecognitionResults(JNIEnv* env, jobject obj,
jobjectArray strings, jfloatArray floats, jboolean provisional) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::vector<base::string16> options;
AppendJavaStringArrayToStringVector(env, strings, &options);
std::vector<float> scores(options.size(), 0.0);
@@ -167,7 +167,7 @@ void SpeechRecognizerImplAndroid::OnRecognitionResults(JNIEnv* env, jobject obj,
void SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread(
SpeechRecognitionResults const &results) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
listener()->OnRecognitionResults(session_id(), results);
}
@@ -179,7 +179,7 @@ void SpeechRecognizerImplAndroid::OnRecognitionError(JNIEnv* env,
static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL), error));
return;
}
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
SpeechRecognitionErrorCode code =
static_cast<SpeechRecognitionErrorCode>(error);
listener()->OnRecognitionError(session_id(), SpeechRecognitionError(code));
@@ -193,7 +193,7 @@ void SpeechRecognizerImplAndroid::OnRecognitionEnd(JNIEnv* env,
static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
return;
}
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
state_ = STATE_IDLE;
listener()->OnRecognitionEnd(session_id());
}
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_android.h b/chromium/content/browser/speech/speech_recognizer_impl_android.h
index cdf0b4db6d8..11895c441fe 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_android.h
+++ b/chromium/content/browser/speech/speech_recognizer_impl_android.h
@@ -24,11 +24,11 @@ class CONTENT_EXPORT SpeechRecognizerImplAndroid : public SpeechRecognizer {
int session_id);
// SpeechRecognizer methods.
- virtual void StartRecognition(const std::string& device_id) override;
- virtual void AbortRecognition() override;
- virtual void StopAudioCapture() override;
- virtual bool IsActive() const override;
- virtual bool IsCapturingAudio() const override;
+ void StartRecognition(const std::string& device_id) override;
+ void AbortRecognition() override;
+ void StopAudioCapture() override;
+ bool IsActive() const override;
+ bool IsCapturingAudio() const override;
// Called from Java methods via JNI.
void OnAudioStart(JNIEnv* env, jobject obj);
@@ -53,7 +53,7 @@ class CONTENT_EXPORT SpeechRecognizerImplAndroid : public SpeechRecognizer {
std::string language, bool continuous, bool interim_results);
void OnRecognitionResultsOnIOThread(SpeechRecognitionResults const &results);
- virtual ~SpeechRecognizerImplAndroid();
+ ~SpeechRecognizerImplAndroid() override;
base::android::ScopedJavaGlobalRef<jobject> j_recognition_;
State state_;
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc b/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
index 7168fb64973..3e8ef284287 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
@@ -380,7 +380,7 @@ TEST_F(SpeechRecognizerImplTest, AudioControllerErrorNoData) {
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO, error_);
+ EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE, error_);
CheckFinalEventsConsistency();
}
@@ -400,7 +400,7 @@ TEST_F(SpeechRecognizerImplTest, AudioControllerErrorWithData) {
EXPECT_TRUE(recognition_started_);
EXPECT_TRUE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO, error_);
+ EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE, error_);
CheckFinalEventsConsistency();
}