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 package org.chromium.content.browser; | 5 package org.chromium.content.browser; |
6 | 6 |
7 import android.content.ComponentName; | 7 import android.content.ComponentName; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.content.Intent; | 9 import android.content.Intent; |
10 import android.content.pm.PackageManager; | 10 import android.content.pm.PackageManager; |
11 import android.content.pm.PackageManager.NameNotFoundException; | 11 import android.content.pm.PackageManager.NameNotFoundException; |
12 import android.content.pm.ResolveInfo; | 12 import android.content.pm.ResolveInfo; |
13 import android.content.pm.ServiceInfo; | 13 import android.content.pm.ServiceInfo; |
14 import android.os.Bundle; | 14 import android.os.Bundle; |
15 import android.speech.RecognitionListener; | 15 import android.speech.RecognitionListener; |
16 import android.speech.RecognitionService; | 16 import android.speech.RecognitionService; |
17 import android.speech.RecognizerIntent; | 17 import android.speech.RecognizerIntent; |
18 import android.speech.SpeechRecognizer; | 18 import android.speech.SpeechRecognizer; |
19 | 19 |
20 import org.chromium.base.CalledByNative; | 20 import org.chromium.base.CalledByNative; |
21 import org.chromium.base.JNINamespace; | 21 import org.chromium.base.JNINamespace; |
| 22 import org.chromium.content_public.common.SpeechRecognitionErrorCode; |
22 | 23 |
23 import java.util.ArrayList; | 24 import java.util.ArrayList; |
24 import java.util.List; | 25 import java.util.List; |
25 | 26 |
26 /** | 27 /** |
27 * This class uses Android's SpeechRecognizer to perform speech recognition for
the Web Speech API | 28 * This class uses Android's SpeechRecognizer to perform speech recognition for
the Web Speech API |
28 * on Android. Using Android's platform recognizer offers several benefits, like
good quality and | 29 * on Android. Using Android's platform recognizer offers several benefits, like
good quality and |
29 * good local fallback when no data connection is available. | 30 * good local fallback when no data connection is available. |
30 */ | 31 */ |
31 @JNINamespace("content") | 32 @JNINamespace("content") |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 nativeOnSoundEnd(mNativeSpeechRecognizerImplAndroid); | 83 nativeOnSoundEnd(mNativeSpeechRecognizerImplAndroid); |
83 // Since Android doesn't have a dedicated event for when audio c
apture is finished, | 84 // Since Android doesn't have a dedicated event for when audio c
apture is finished, |
84 // we fire it after speech has ended. | 85 // we fire it after speech has ended. |
85 nativeOnAudioEnd(mNativeSpeechRecognizerImplAndroid); | 86 nativeOnAudioEnd(mNativeSpeechRecognizerImplAndroid); |
86 mState = STATE_IDLE; | 87 mState = STATE_IDLE; |
87 } | 88 } |
88 } | 89 } |
89 | 90 |
90 @Override | 91 @Override |
91 public void onError(int error) { | 92 public void onError(int error) { |
92 int code = SpeechRecognitionError.NONE; | 93 int code = SpeechRecognitionErrorCode.NONE; |
93 | 94 |
94 // Translate Android SpeechRecognizer errors to Web Speech API error
s. | 95 // Translate Android SpeechRecognizer errors to Web Speech API error
s. |
95 switch(error) { | 96 switch(error) { |
96 case SpeechRecognizer.ERROR_AUDIO: | 97 case SpeechRecognizer.ERROR_AUDIO: |
97 code = SpeechRecognitionError.AUDIO; | 98 code = SpeechRecognitionErrorCode.AUDIO; |
98 break; | 99 break; |
99 case SpeechRecognizer.ERROR_CLIENT: | 100 case SpeechRecognizer.ERROR_CLIENT: |
100 code = SpeechRecognitionError.ABORTED; | 101 code = SpeechRecognitionErrorCode.ABORTED; |
101 break; | 102 break; |
102 case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: | 103 case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: |
103 case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS: | 104 case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS: |
104 code = SpeechRecognitionError.NOT_ALLOWED; | 105 code = SpeechRecognitionErrorCode.NOT_ALLOWED; |
105 break; | 106 break; |
106 case SpeechRecognizer.ERROR_NETWORK_TIMEOUT: | 107 case SpeechRecognizer.ERROR_NETWORK_TIMEOUT: |
107 case SpeechRecognizer.ERROR_NETWORK: | 108 case SpeechRecognizer.ERROR_NETWORK: |
108 case SpeechRecognizer.ERROR_SERVER: | 109 case SpeechRecognizer.ERROR_SERVER: |
109 code = SpeechRecognitionError.NETWORK; | 110 code = SpeechRecognitionErrorCode.NETWORK; |
110 break; | 111 break; |
111 case SpeechRecognizer.ERROR_NO_MATCH: | 112 case SpeechRecognizer.ERROR_NO_MATCH: |
112 code = SpeechRecognitionError.NO_MATCH; | 113 code = SpeechRecognitionErrorCode.NO_MATCH; |
113 break; | 114 break; |
114 case SpeechRecognizer.ERROR_SPEECH_TIMEOUT: | 115 case SpeechRecognizer.ERROR_SPEECH_TIMEOUT: |
115 code = SpeechRecognitionError.NO_SPEECH; | 116 code = SpeechRecognitionErrorCode.NO_SPEECH; |
116 break; | 117 break; |
117 default: | 118 default: |
118 assert false; | 119 assert false; |
119 return; | 120 return; |
120 } | 121 } |
121 | 122 |
122 terminate(code); | 123 terminate(code); |
123 } | 124 } |
124 | 125 |
125 @Override | 126 @Override |
126 public void onEvent(int event, Bundle bundle) { } | 127 public void onEvent(int event, Bundle bundle) { } |
127 | 128 |
128 @Override | 129 @Override |
129 public void onPartialResults(Bundle bundle) { | 130 public void onPartialResults(Bundle bundle) { |
130 handleResults(bundle, true); | 131 handleResults(bundle, true); |
131 } | 132 } |
132 | 133 |
133 @Override | 134 @Override |
134 public void onReadyForSpeech(Bundle bundle) { | 135 public void onReadyForSpeech(Bundle bundle) { |
135 mState = STATE_AWAITING_SPEECH; | 136 mState = STATE_AWAITING_SPEECH; |
136 nativeOnAudioStart(mNativeSpeechRecognizerImplAndroid); | 137 nativeOnAudioStart(mNativeSpeechRecognizerImplAndroid); |
137 } | 138 } |
138 | 139 |
139 @Override | 140 @Override |
140 public void onResults(Bundle bundle) { | 141 public void onResults(Bundle bundle) { |
141 handleResults(bundle, false); | 142 handleResults(bundle, false); |
142 // We assume that onResults is called only once, at the end of a ses
sion, thus we | 143 // We assume that onResults is called only once, at the end of a ses
sion, thus we |
143 // terminate. If one day the recognition provider changes dictation
mode behavior to | 144 // terminate. If one day the recognition provider changes dictation
mode behavior to |
144 // call onResults several times, we should terminate only if (!mCont
inuous). | 145 // call onResults several times, we should terminate only if (!mCont
inuous). |
145 terminate(SpeechRecognitionError.NONE); | 146 terminate(SpeechRecognitionErrorCode.NONE); |
146 } | 147 } |
147 | 148 |
148 @Override | 149 @Override |
149 public void onRmsChanged(float rms) { } | 150 public void onRmsChanged(float rms) { } |
150 | 151 |
151 private void handleResults(Bundle bundle, boolean provisional) { | 152 private void handleResults(Bundle bundle, boolean provisional) { |
152 if (mContinuous && provisional) { | 153 if (mContinuous && provisional) { |
153 // In continuous mode, Android's recognizer sends final results
as provisional. | 154 // In continuous mode, Android's recognizer sends final results
as provisional. |
154 provisional = false; | 155 provisional = false; |
155 } | 156 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 private void terminate(int error) { | 231 private void terminate(int error) { |
231 | 232 |
232 if (mState != STATE_IDLE) { | 233 if (mState != STATE_IDLE) { |
233 if (mState == STATE_CAPTURING_SPEECH) { | 234 if (mState == STATE_CAPTURING_SPEECH) { |
234 nativeOnSoundEnd(mNativeSpeechRecognizerImplAndroid); | 235 nativeOnSoundEnd(mNativeSpeechRecognizerImplAndroid); |
235 } | 236 } |
236 nativeOnAudioEnd(mNativeSpeechRecognizerImplAndroid); | 237 nativeOnAudioEnd(mNativeSpeechRecognizerImplAndroid); |
237 mState = STATE_IDLE; | 238 mState = STATE_IDLE; |
238 } | 239 } |
239 | 240 |
240 if (error != SpeechRecognitionError.NONE) | 241 if (error != SpeechRecognitionErrorCode.NONE) |
241 nativeOnRecognitionError(mNativeSpeechRecognizerImplAndroid, error); | 242 nativeOnRecognitionError(mNativeSpeechRecognizerImplAndroid, error); |
242 | 243 |
243 mRecognizer.destroy(); | 244 mRecognizer.destroy(); |
244 mRecognizer = null; | 245 mRecognizer = null; |
245 nativeOnRecognitionEnd(mNativeSpeechRecognizerImplAndroid); | 246 nativeOnRecognitionEnd(mNativeSpeechRecognizerImplAndroid); |
246 mNativeSpeechRecognizerImplAndroid = 0; | 247 mNativeSpeechRecognizerImplAndroid = 0; |
247 } | 248 } |
248 | 249 |
249 @CalledByNative | 250 @CalledByNative |
250 private static SpeechRecognition createSpeechRecognition( | 251 private static SpeechRecognition createSpeechRecognition( |
(...skipping 12 matching lines...) Expand all Loading... |
263 mIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, interimResults)
; | 264 mIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, interimResults)
; |
264 mRecognizer.startListening(mIntent); | 265 mRecognizer.startListening(mIntent); |
265 } | 266 } |
266 | 267 |
267 @CalledByNative | 268 @CalledByNative |
268 private void abortRecognition() { | 269 private void abortRecognition() { |
269 if (mRecognizer == null) | 270 if (mRecognizer == null) |
270 return; | 271 return; |
271 | 272 |
272 mRecognizer.cancel(); | 273 mRecognizer.cancel(); |
273 terminate(SpeechRecognitionError.ABORTED); | 274 terminate(SpeechRecognitionErrorCode.ABORTED); |
274 } | 275 } |
275 | 276 |
276 @CalledByNative | 277 @CalledByNative |
277 private void stopRecognition() { | 278 private void stopRecognition() { |
278 if (mRecognizer == null) | 279 if (mRecognizer == null) |
279 return; | 280 return; |
280 | 281 |
281 mContinuous = false; | 282 mContinuous = false; |
282 mRecognizer.stopListening(); | 283 mRecognizer.stopListening(); |
283 } | 284 } |
284 | 285 |
285 // Native JNI calls to content/browser/speech/speech_recognizer_impl_android
.cc | 286 // Native JNI calls to content/browser/speech/speech_recognizer_impl_android
.cc |
286 private native void nativeOnAudioStart(long nativeSpeechRecognizerImplAndroi
d); | 287 private native void nativeOnAudioStart(long nativeSpeechRecognizerImplAndroi
d); |
287 private native void nativeOnSoundStart(long nativeSpeechRecognizerImplAndroi
d); | 288 private native void nativeOnSoundStart(long nativeSpeechRecognizerImplAndroi
d); |
288 private native void nativeOnSoundEnd(long nativeSpeechRecognizerImplAndroid)
; | 289 private native void nativeOnSoundEnd(long nativeSpeechRecognizerImplAndroid)
; |
289 private native void nativeOnAudioEnd(long nativeSpeechRecognizerImplAndroid)
; | 290 private native void nativeOnAudioEnd(long nativeSpeechRecognizerImplAndroid)
; |
290 private native void nativeOnRecognitionResults(long nativeSpeechRecognizerIm
plAndroid, | 291 private native void nativeOnRecognitionResults(long nativeSpeechRecognizerIm
plAndroid, |
291 String[] results, | 292 String[] results, |
292 float[] scores, | 293 float[] scores, |
293 boolean provisional); | 294 boolean provisional); |
294 private native void nativeOnRecognitionError(long nativeSpeechRecognizerImpl
Android, int error); | 295 private native void nativeOnRecognitionError(long nativeSpeechRecognizerImpl
Android, int error); |
295 private native void nativeOnRecognitionEnd(long nativeSpeechRecognizerImplAn
droid); | 296 private native void nativeOnRecognitionEnd(long nativeSpeechRecognizerImplAn
droid); |
296 } | 297 } |
OLD | NEW |