| Index: content/browser/speech/speech_recognizer_impl_android.cc
|
| diff --git a/content/browser/speech/speech_recognizer_impl_android.cc b/content/browser/speech/speech_recognizer_impl_android.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..df36aa0063f074b9a74405712439580b5b510ef0
|
| --- /dev/null
|
| +++ b/content/browser/speech/speech_recognizer_impl_android.cc
|
| @@ -0,0 +1,202 @@
|
| +// Copyright (c) 2013 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 "content/browser/speech/speech_recognizer_impl_android.h"
|
| +
|
| +#include "base/android/jni_android.h"
|
| +#include "base/android/jni_array.h"
|
| +#include "base/android/jni_string.h"
|
| +#include "base/android/scoped_java_ref.h"
|
| +#include "base/bind.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/speech_recognition_event_listener.h"
|
| +#include "content/public/browser/speech_recognition_manager.h"
|
| +#include "content/public/browser/speech_recognition_session_config.h"
|
| +#include "content/public/common/speech_recognition_grammar.h"
|
| +#include "content/public/common/speech_recognition_result.h"
|
| +#include "jni/SpeechRecognition_jni.h"
|
| +
|
| +using base::android::AppendJavaStringArrayToStringVector;
|
| +using base::android::AttachCurrentThread;
|
| +using base::android::GetApplicationContext;
|
| +using base::android::JavaFloatArrayToFloatVector;
|
| +
|
| +namespace content {
|
| +
|
| +SpeechRecognizerImplAndroid::SpeechRecognizerImplAndroid(
|
| + SpeechRecognitionEventListener* listener,
|
| + int session_id)
|
| + : SpeechRecognizer(listener, session_id),
|
| + state_(STATE_IDLE) {
|
| +}
|
| +
|
| +SpeechRecognizerImplAndroid::~SpeechRecognizerImplAndroid() { }
|
| +
|
| +void SpeechRecognizerImplAndroid::StartRecognition() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
|
| + &SpeechRecognitionEventListener::OnRecognitionStart,
|
| + base::Unretained(listener()),
|
| + session_id()));
|
| + SpeechRecognitionSessionConfig config =
|
| + SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id());
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
|
| + &content::SpeechRecognizerImplAndroid::StartRecognitionOnUIThread, this,
|
| + config.continuous, config.interim_results));
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::StartRecognitionOnUIThread(
|
| + bool continuous, bool interim_results) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + JNIEnv* env = AttachCurrentThread();
|
| + j_recognition_.Reset(Java_SpeechRecognition_createSpeechRecognition(env,
|
| + GetApplicationContext(), reinterpret_cast<jint>(this)));
|
| + Java_SpeechRecognition_startRecognition(env, j_recognition_.obj(), continuous,
|
| + interim_results);
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::AbortRecognition() {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
| + state_ = STATE_IDLE;
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
|
| + &content::SpeechRecognizerImplAndroid::AbortRecognition, this));
|
| + return;
|
| + }
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + JNIEnv* env = AttachCurrentThread();
|
| + if (!j_recognition_.is_null())
|
| + Java_SpeechRecognition_abortRecognition(env, j_recognition_.obj());
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::StopAudioCapture() {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
|
| + &content::SpeechRecognizerImplAndroid::StopAudioCapture, this));
|
| + return;
|
| + }
|
| + DCHECK(BrowserThread::CurrentlyOn(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));
|
| + return state_ != STATE_IDLE;
|
| +}
|
| +
|
| +bool SpeechRecognizerImplAndroid::IsCapturingAudio() const {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return state_ == STATE_CAPTURING_AUDIO;
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::OnAudioStart(JNIEnv* env, jobject obj) {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
|
| + &SpeechRecognizerImplAndroid::OnAudioStart, this,
|
| + static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
|
| + return;
|
| + }
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + state_ = STATE_CAPTURING_AUDIO;
|
| + listener()->OnAudioStart(session_id());
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::OnSoundStart(JNIEnv* env, jobject obj) {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
|
| + &SpeechRecognizerImplAndroid::OnSoundStart, this,
|
| + static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
|
| + return;
|
| + }
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + listener()->OnSoundStart(session_id());
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::OnSoundEnd(JNIEnv* env, jobject obj) {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
|
| + &SpeechRecognizerImplAndroid::OnSoundEnd, this,
|
| + static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
|
| + return;
|
| + }
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + listener()->OnSoundEnd(session_id());
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env, jobject obj) {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
|
| + &SpeechRecognizerImplAndroid::OnAudioEnd, this,
|
| + static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
|
| + return;
|
| + }
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + if (state_ == STATE_CAPTURING_AUDIO)
|
| + state_ = STATE_AWAITING_FINAL_RESULT;
|
| + listener()->OnAudioEnd(session_id());
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::OnRecognitionResults(JNIEnv* env, jobject obj,
|
| + jobjectArray strings, jfloatArray floats, jboolean provisional) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + std::vector<string16> options;
|
| + AppendJavaStringArrayToStringVector(env, strings, &options);
|
| + std::vector<float> scores(options.size(), 0.0);
|
| + if (floats != NULL)
|
| + JavaFloatArrayToFloatVector(env, floats, &scores);
|
| + SpeechRecognitionResults results;
|
| + results.push_back(SpeechRecognitionResult());
|
| + SpeechRecognitionResult& result = results.back();
|
| + CHECK_EQ(options.size(), scores.size());
|
| + for (size_t i = 0; i < options.size(); ++i) {
|
| + result.hypotheses.push_back(SpeechRecognitionHypothesis(
|
| + options[i], static_cast<double>(scores[i])));
|
| + }
|
| + result.is_provisional = provisional;
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
|
| + &SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread,
|
| + this, results));
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread(
|
| + SpeechRecognitionResults const &results) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + listener()->OnRecognitionResults(session_id(), results);
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::OnRecognitionError(JNIEnv* env,
|
| + jobject obj, jint error) {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
|
| + &SpeechRecognizerImplAndroid::OnRecognitionError, this,
|
| + static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL), error));
|
| + return;
|
| + }
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + SpeechRecognitionErrorCode code =
|
| + static_cast<SpeechRecognitionErrorCode>(error);
|
| + listener()->OnRecognitionError(session_id(), SpeechRecognitionError(code));
|
| +}
|
| +
|
| +void SpeechRecognizerImplAndroid::OnRecognitionEnd(JNIEnv* env,
|
| + jobject obj) {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
|
| + &SpeechRecognizerImplAndroid::OnRecognitionEnd, this,
|
| + static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
|
| + return;
|
| + }
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + state_ = STATE_IDLE;
|
| + listener()->OnRecognitionEnd(session_id());
|
| +}
|
| +
|
| +// static
|
| +bool SpeechRecognizerImplAndroid::RegisterSpeechRecognizer(JNIEnv* env) {
|
| + return RegisterNativesImpl(env);
|
| +}
|
| +
|
| +} // namespace content
|
|
|