OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/speech/speech_recognizer_impl_android.h" | 5 #include "content/browser/speech/speech_recognizer_impl_android.h" |
6 | 6 |
7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
8 #include "base/android/jni_array.h" | 8 #include "base/android/jni_array.h" |
9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
10 #include "base/android/scoped_java_ref.h" | 10 #include "base/android/scoped_java_ref.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 SpeechRecognitionEventListener* listener, | 30 SpeechRecognitionEventListener* listener, |
31 int session_id) | 31 int session_id) |
32 : SpeechRecognizer(listener, session_id), | 32 : SpeechRecognizer(listener, session_id), |
33 state_(STATE_IDLE) { | 33 state_(STATE_IDLE) { |
34 } | 34 } |
35 | 35 |
36 SpeechRecognizerImplAndroid::~SpeechRecognizerImplAndroid() { } | 36 SpeechRecognizerImplAndroid::~SpeechRecognizerImplAndroid() { } |
37 | 37 |
38 void SpeechRecognizerImplAndroid::StartRecognition( | 38 void SpeechRecognizerImplAndroid::StartRecognition( |
39 const std::string& device_id) { | 39 const std::string& device_id) { |
40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 40 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
41 // TODO(xians): Open the correct device for speech on Android. | 41 // TODO(xians): Open the correct device for speech on Android. |
42 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 42 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
43 &SpeechRecognitionEventListener::OnRecognitionStart, | 43 &SpeechRecognitionEventListener::OnRecognitionStart, |
44 base::Unretained(listener()), | 44 base::Unretained(listener()), |
45 session_id())); | 45 session_id())); |
46 SpeechRecognitionSessionConfig config = | 46 SpeechRecognitionSessionConfig config = |
47 SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id()); | 47 SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id()); |
48 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | 48 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
49 &content::SpeechRecognizerImplAndroid::StartRecognitionOnUIThread, this, | 49 &content::SpeechRecognizerImplAndroid::StartRecognitionOnUIThread, this, |
50 config.language, config.continuous, config.interim_results)); | 50 config.language, config.continuous, config.interim_results)); |
51 } | 51 } |
52 | 52 |
53 void SpeechRecognizerImplAndroid::StartRecognitionOnUIThread( | 53 void SpeechRecognizerImplAndroid::StartRecognitionOnUIThread( |
54 std::string language, bool continuous, bool interim_results) { | 54 std::string language, bool continuous, bool interim_results) { |
55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 55 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
56 JNIEnv* env = AttachCurrentThread(); | 56 JNIEnv* env = AttachCurrentThread(); |
57 j_recognition_.Reset(Java_SpeechRecognition_createSpeechRecognition(env, | 57 j_recognition_.Reset(Java_SpeechRecognition_createSpeechRecognition(env, |
58 GetApplicationContext(), reinterpret_cast<intptr_t>(this))); | 58 GetApplicationContext(), reinterpret_cast<intptr_t>(this))); |
59 Java_SpeechRecognition_startRecognition(env, j_recognition_.obj(), | 59 Java_SpeechRecognition_startRecognition(env, j_recognition_.obj(), |
60 ConvertUTF8ToJavaString(env, language).obj(), continuous, | 60 ConvertUTF8ToJavaString(env, language).obj(), continuous, |
61 interim_results); | 61 interim_results); |
62 } | 62 } |
63 | 63 |
64 void SpeechRecognizerImplAndroid::AbortRecognition() { | 64 void SpeechRecognizerImplAndroid::AbortRecognition() { |
65 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 65 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
66 state_ = STATE_IDLE; | 66 state_ = STATE_IDLE; |
67 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | 67 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
68 &content::SpeechRecognizerImplAndroid::AbortRecognition, this)); | 68 &content::SpeechRecognizerImplAndroid::AbortRecognition, this)); |
69 return; | 69 return; |
70 } | 70 } |
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 71 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
72 JNIEnv* env = AttachCurrentThread(); | 72 JNIEnv* env = AttachCurrentThread(); |
73 if (!j_recognition_.is_null()) | 73 if (!j_recognition_.is_null()) |
74 Java_SpeechRecognition_abortRecognition(env, j_recognition_.obj()); | 74 Java_SpeechRecognition_abortRecognition(env, j_recognition_.obj()); |
75 } | 75 } |
76 | 76 |
77 void SpeechRecognizerImplAndroid::StopAudioCapture() { | 77 void SpeechRecognizerImplAndroid::StopAudioCapture() { |
78 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 78 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
79 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | 79 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
80 &content::SpeechRecognizerImplAndroid::StopAudioCapture, this)); | 80 &content::SpeechRecognizerImplAndroid::StopAudioCapture, this)); |
81 return; | 81 return; |
82 } | 82 } |
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 83 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
84 JNIEnv* env = AttachCurrentThread(); | 84 JNIEnv* env = AttachCurrentThread(); |
85 if (!j_recognition_.is_null()) | 85 if (!j_recognition_.is_null()) |
86 Java_SpeechRecognition_stopRecognition(env, j_recognition_.obj()); | 86 Java_SpeechRecognition_stopRecognition(env, j_recognition_.obj()); |
87 } | 87 } |
88 | 88 |
89 bool SpeechRecognizerImplAndroid::IsActive() const { | 89 bool SpeechRecognizerImplAndroid::IsActive() const { |
90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 90 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
91 return state_ != STATE_IDLE; | 91 return state_ != STATE_IDLE; |
92 } | 92 } |
93 | 93 |
94 bool SpeechRecognizerImplAndroid::IsCapturingAudio() const { | 94 bool SpeechRecognizerImplAndroid::IsCapturingAudio() const { |
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 95 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
96 return state_ == STATE_CAPTURING_AUDIO; | 96 return state_ == STATE_CAPTURING_AUDIO; |
97 } | 97 } |
98 | 98 |
99 void SpeechRecognizerImplAndroid::OnAudioStart(JNIEnv* env, jobject obj) { | 99 void SpeechRecognizerImplAndroid::OnAudioStart(JNIEnv* env, jobject obj) { |
100 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 100 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
101 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 101 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
102 &SpeechRecognizerImplAndroid::OnAudioStart, this, | 102 &SpeechRecognizerImplAndroid::OnAudioStart, this, |
103 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); | 103 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); |
104 return; | 104 return; |
105 } | 105 } |
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 106 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
107 state_ = STATE_CAPTURING_AUDIO; | 107 state_ = STATE_CAPTURING_AUDIO; |
108 listener()->OnAudioStart(session_id()); | 108 listener()->OnAudioStart(session_id()); |
109 } | 109 } |
110 | 110 |
111 void SpeechRecognizerImplAndroid::OnSoundStart(JNIEnv* env, jobject obj) { | 111 void SpeechRecognizerImplAndroid::OnSoundStart(JNIEnv* env, jobject obj) { |
112 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 112 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
113 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 113 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
114 &SpeechRecognizerImplAndroid::OnSoundStart, this, | 114 &SpeechRecognizerImplAndroid::OnSoundStart, this, |
115 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); | 115 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); |
116 return; | 116 return; |
117 } | 117 } |
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 118 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
119 listener()->OnSoundStart(session_id()); | 119 listener()->OnSoundStart(session_id()); |
120 } | 120 } |
121 | 121 |
122 void SpeechRecognizerImplAndroid::OnSoundEnd(JNIEnv* env, jobject obj) { | 122 void SpeechRecognizerImplAndroid::OnSoundEnd(JNIEnv* env, jobject obj) { |
123 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 123 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
124 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 124 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
125 &SpeechRecognizerImplAndroid::OnSoundEnd, this, | 125 &SpeechRecognizerImplAndroid::OnSoundEnd, this, |
126 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); | 126 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); |
127 return; | 127 return; |
128 } | 128 } |
129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 129 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
130 listener()->OnSoundEnd(session_id()); | 130 listener()->OnSoundEnd(session_id()); |
131 } | 131 } |
132 | 132 |
133 void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env, jobject obj) { | 133 void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env, jobject obj) { |
134 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 134 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
135 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 135 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
136 &SpeechRecognizerImplAndroid::OnAudioEnd, this, | 136 &SpeechRecognizerImplAndroid::OnAudioEnd, this, |
137 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); | 137 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); |
138 return; | 138 return; |
139 } | 139 } |
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 140 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
141 if (state_ == STATE_CAPTURING_AUDIO) | 141 if (state_ == STATE_CAPTURING_AUDIO) |
142 state_ = STATE_AWAITING_FINAL_RESULT; | 142 state_ = STATE_AWAITING_FINAL_RESULT; |
143 listener()->OnAudioEnd(session_id()); | 143 listener()->OnAudioEnd(session_id()); |
144 } | 144 } |
145 | 145 |
146 void SpeechRecognizerImplAndroid::OnRecognitionResults(JNIEnv* env, jobject obj, | 146 void SpeechRecognizerImplAndroid::OnRecognitionResults(JNIEnv* env, jobject obj, |
147 jobjectArray strings, jfloatArray floats, jboolean provisional) { | 147 jobjectArray strings, jfloatArray floats, jboolean provisional) { |
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 148 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
149 std::vector<base::string16> options; | 149 std::vector<base::string16> options; |
150 AppendJavaStringArrayToStringVector(env, strings, &options); | 150 AppendJavaStringArrayToStringVector(env, strings, &options); |
151 std::vector<float> scores(options.size(), 0.0); | 151 std::vector<float> scores(options.size(), 0.0); |
152 if (floats != NULL) | 152 if (floats != NULL) |
153 JavaFloatArrayToFloatVector(env, floats, &scores); | 153 JavaFloatArrayToFloatVector(env, floats, &scores); |
154 SpeechRecognitionResults results; | 154 SpeechRecognitionResults results; |
155 results.push_back(SpeechRecognitionResult()); | 155 results.push_back(SpeechRecognitionResult()); |
156 SpeechRecognitionResult& result = results.back(); | 156 SpeechRecognitionResult& result = results.back(); |
157 CHECK_EQ(options.size(), scores.size()); | 157 CHECK_EQ(options.size(), scores.size()); |
158 for (size_t i = 0; i < options.size(); ++i) { | 158 for (size_t i = 0; i < options.size(); ++i) { |
159 result.hypotheses.push_back(SpeechRecognitionHypothesis( | 159 result.hypotheses.push_back(SpeechRecognitionHypothesis( |
160 options[i], static_cast<double>(scores[i]))); | 160 options[i], static_cast<double>(scores[i]))); |
161 } | 161 } |
162 result.is_provisional = provisional; | 162 result.is_provisional = provisional; |
163 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 163 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
164 &SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread, | 164 &SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread, |
165 this, results)); | 165 this, results)); |
166 } | 166 } |
167 | 167 |
168 void SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread( | 168 void SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread( |
169 SpeechRecognitionResults const &results) { | 169 SpeechRecognitionResults const &results) { |
170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 170 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
171 listener()->OnRecognitionResults(session_id(), results); | 171 listener()->OnRecognitionResults(session_id(), results); |
172 } | 172 } |
173 | 173 |
174 void SpeechRecognizerImplAndroid::OnRecognitionError(JNIEnv* env, | 174 void SpeechRecognizerImplAndroid::OnRecognitionError(JNIEnv* env, |
175 jobject obj, jint error) { | 175 jobject obj, jint error) { |
176 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 176 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
177 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 177 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
178 &SpeechRecognizerImplAndroid::OnRecognitionError, this, | 178 &SpeechRecognizerImplAndroid::OnRecognitionError, this, |
179 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL), error)); | 179 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL), error)); |
180 return; | 180 return; |
181 } | 181 } |
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 182 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
183 SpeechRecognitionErrorCode code = | 183 SpeechRecognitionErrorCode code = |
184 static_cast<SpeechRecognitionErrorCode>(error); | 184 static_cast<SpeechRecognitionErrorCode>(error); |
185 listener()->OnRecognitionError(session_id(), SpeechRecognitionError(code)); | 185 listener()->OnRecognitionError(session_id(), SpeechRecognitionError(code)); |
186 } | 186 } |
187 | 187 |
188 void SpeechRecognizerImplAndroid::OnRecognitionEnd(JNIEnv* env, | 188 void SpeechRecognizerImplAndroid::OnRecognitionEnd(JNIEnv* env, |
189 jobject obj) { | 189 jobject obj) { |
190 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 190 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
191 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 191 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
192 &SpeechRecognizerImplAndroid::OnRecognitionEnd, this, | 192 &SpeechRecognizerImplAndroid::OnRecognitionEnd, this, |
193 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); | 193 static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL))); |
194 return; | 194 return; |
195 } | 195 } |
196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 196 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
197 state_ = STATE_IDLE; | 197 state_ = STATE_IDLE; |
198 listener()->OnRecognitionEnd(session_id()); | 198 listener()->OnRecognitionEnd(session_id()); |
199 } | 199 } |
200 | 200 |
201 // static | 201 // static |
202 bool SpeechRecognizerImplAndroid::RegisterSpeechRecognizer(JNIEnv* env) { | 202 bool SpeechRecognizerImplAndroid::RegisterSpeechRecognizer(JNIEnv* env) { |
203 return RegisterNativesImpl(env); | 203 return RegisterNativesImpl(env); |
204 } | 204 } |
205 | 205 |
206 } // namespace content | 206 } // namespace content |
OLD | NEW |