diff options
| -rw-r--r-- | core/api/current.txt | 5 | ||||
| -rw-r--r-- | core/java/android/speech/IRecognitionListener.aidl | 18 | ||||
| -rw-r--r-- | core/java/android/speech/RecognitionListener.java | 27 | ||||
| -rw-r--r-- | core/java/android/speech/RecognitionService.java | 21 | ||||
| -rw-r--r-- | core/java/android/speech/RecognizerIntent.java | 12 | ||||
| -rw-r--r-- | core/java/android/speech/SpeechRecognizer.java | 16 | ||||
| -rw-r--r-- | services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java | 14 |
7 files changed, 112 insertions, 1 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 894910d3bf89..eba745409756 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -39371,6 +39371,7 @@ package android.speech { public interface RecognitionListener { method public void onBeginningOfSpeech(); method public void onBufferReceived(byte[]); + method public default void onEndOfSegmentedSession(); method public void onEndOfSpeech(); method public void onError(int); method public void onEvent(int, android.os.Bundle); @@ -39378,6 +39379,7 @@ package android.speech { method public void onReadyForSpeech(android.os.Bundle); method public void onResults(android.os.Bundle); method public void onRmsChanged(float); + method public default void onSegmentResults(@NonNull android.os.Bundle); } public abstract class RecognitionService extends android.app.Service { @@ -39395,6 +39397,7 @@ package android.speech { public class RecognitionService.Callback { method public void beginningOfSpeech() throws android.os.RemoteException; method public void bufferReceived(byte[]) throws android.os.RemoteException; + method public void endOfSegmentedSession() throws android.os.RemoteException; method public void endOfSpeech() throws android.os.RemoteException; method public void error(int) throws android.os.RemoteException; method @NonNull public android.content.AttributionSource getCallingAttributionSource(); @@ -39403,6 +39406,7 @@ package android.speech { method public void readyForSpeech(android.os.Bundle) throws android.os.RemoteException; method public void results(android.os.Bundle) throws android.os.RemoteException; method public void rmsChanged(float) throws android.os.RemoteException; + method public void segmentResults(@NonNull android.os.Bundle) throws android.os.RemoteException; } public static class RecognitionService.SupportCallback { @@ -39458,6 +39462,7 @@ package android.speech { field public static final String EXTRA_RESULTS_PENDINGINTENT = "android.speech.extra.RESULTS_PENDINGINTENT"; field public static final String EXTRA_RESULTS_PENDINGINTENT_BUNDLE = "android.speech.extra.RESULTS_PENDINGINTENT_BUNDLE"; field public static final String EXTRA_SECURE = "android.speech.extras.EXTRA_SECURE"; + field public static final String EXTRA_SEGMENT_SESSION = "android.speech.extra.SEGMENT_SESSION"; field public static final String EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS = "android.speech.extras.SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS"; field public static final String EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS = "android.speech.extras.SPEECH_INPUT_MINIMUM_LENGTH_MILLIS"; field public static final String EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS = "android.speech.extras.SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS"; diff --git a/core/java/android/speech/IRecognitionListener.aidl b/core/java/android/speech/IRecognitionListener.aidl index 7c79b1ae15de..986a41c64053 100644 --- a/core/java/android/speech/IRecognitionListener.aidl +++ b/core/java/android/speech/IRecognitionListener.aidl @@ -78,6 +78,24 @@ oneway interface IRecognitionListener { void onPartialResults(in Bundle results); /** + * Called for each ready segment of a recognition request. To request segmented speech results + * use {@link RecognizerIntent#EXTRA_SEGMENT_SESSION}. The callback might be called + * any number of times between {@link #onBeginningOfSpeech()} and + * {@link #onEndOfSegmentedSession()}. + * + * @param segmentResults the returned results. To retrieve the results in + * ArrayList<String> format use {@link Bundle#getStringArrayList(String)} with + * {@link SpeechRecognizer#RESULTS_RECOGNITION} as a parameter + */ + void onSegmentResults(in Bundle results); + + /** + * Called at the end of a segmented recognition request. To request segmented speech results + * use {@link RecognizerIntent#EXTRA_SEGMENT_SESSION}. + */ + void onEndOfSegmentedSession(); + + /** * Reserved for adding future events. * * @param eventType the type of the occurred event diff --git a/core/java/android/speech/RecognitionListener.java b/core/java/android/speech/RecognitionListener.java index c94b60f847f4..64fd09ff7faf 100644 --- a/core/java/android/speech/RecognitionListener.java +++ b/core/java/android/speech/RecognitionListener.java @@ -15,6 +15,7 @@ */ package android.speech; +import android.annotation.NonNull; import android.content.Intent; import android.os.Bundle; @@ -69,7 +70,13 @@ public interface RecognitionListener { /** * Called when recognition results are ready. - * + * + * <p> + * Called with the results for the full speech since {@link #onReadyForSpeech(Bundle)}. + * To get recognition results in segments rather than for the full session see + * {@link RecognizerIntent#EXTRA_SEGMENT_SESSION}. + * </p> + * * @param results the recognition results. To retrieve the results in {@code * ArrayList<String>} format use {@link Bundle#getStringArrayList(String)} with * {@link SpeechRecognizer#RESULTS_RECOGNITION} as a parameter. A float array of @@ -92,6 +99,24 @@ public interface RecognitionListener { void onPartialResults(Bundle partialResults); /** + * Called for each ready segment of a recognition request. To request segmented speech results + * use {@link RecognizerIntent#EXTRA_SEGMENT_SESSION}. The callback might be called + * any number of times between {@link #onReadyForSpeech(Bundle)} and + * {@link #onEndOfSegmentedSession()}. + * + * @param segmentResults the returned results. To retrieve the results in + * ArrayList<String> format use {@link Bundle#getStringArrayList(String)} with + * {@link SpeechRecognizer#RESULTS_RECOGNITION} as a parameter + */ + default void onSegmentResults(@NonNull Bundle segmentResults) {} + + /** + * Called at the end of a segmented recognition request. To request segmented speech results + * use {@link RecognizerIntent#EXTRA_SEGMENT_SESSION}. + */ + default void onEndOfSegmentedSession() {} + + /** * Reserved for adding future events. * * @param eventType the type of the occurred event diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java index 5dbbc045077e..22cffc1579d1 100644 --- a/core/java/android/speech/RecognitionService.java +++ b/core/java/android/speech/RecognitionService.java @@ -427,6 +427,27 @@ public abstract class RecognitionService extends Service { } /** + * The service should call this method for each ready segment of a long recognition session. + * + * @param results the recognition results. To retrieve the results in {@code + * ArrayList<String>} format use {@link Bundle#getStringArrayList(String)} with + * {@link SpeechRecognizer#RESULTS_RECOGNITION} as a parameter + */ + @SuppressLint({"CallbackMethodName", "RethrowRemoteException"}) + public void segmentResults(@NonNull Bundle results) throws RemoteException { + mListener.onSegmentResults(results); + } + + /** + * The service should call this method to end a segmented session. + */ + @SuppressLint({"CallbackMethodName", "RethrowRemoteException"}) + public void endOfSegmentedSession() throws RemoteException { + Message.obtain(mHandler, MSG_RESET).sendToTarget(); + mListener.onEndOfSegmentedSession(); + } + + /** * Return the Linux uid assigned to the process that sent you the current transaction that * is being processed. This is obtained from {@link Binder#getCallingUid()}. */ diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java index 3183f15fe16c..271e3072c4d9 100644 --- a/core/java/android/speech/RecognizerIntent.java +++ b/core/java/android/speech/RecognizerIntent.java @@ -426,4 +426,16 @@ public class RecognizerIntent { * */ public static final String EXTRA_PREFER_OFFLINE = "android.speech.extra.PREFER_OFFLINE"; + + /** + * Optional boolean, when true and supported by the recognizer implementation it will split + * the recognition results in segments, returned via + * {@link RecognitionListener#onSegmentResults(Bundle)} and terminate the session with + * {@link RecognitionListener#onEndOfSegmentedSession()}. There will be no call to + * {@link RecognitionListener#onResults(Bundle)}. Callers can use + * {@link #EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS} and + * {@link #EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS} to tune how long the segments + * will be. Defaults to false. + */ + public static final String EXTRA_SEGMENT_SESSION = "android.speech.extra.SEGMENT_SESSION"; } diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java index 71c1e882a1f6..502558e355e6 100644 --- a/core/java/android/speech/SpeechRecognizer.java +++ b/core/java/android/speech/SpeechRecognizer.java @@ -768,6 +768,8 @@ public class SpeechRecognizer { private static final int MSG_PARTIAL_RESULTS = 7; private static final int MSG_RMS_CHANGED = 8; private static final int MSG_ON_EVENT = 9; + private static final int MSG_SEGMENT_RESULTS = 10; + private static final int MSG_SEGMENT_END_SESSION = 11; private final Handler mInternalHandler = new Handler(Looper.getMainLooper()) { @Override @@ -803,6 +805,12 @@ public class SpeechRecognizer { case MSG_ON_EVENT: mInternalListener.onEvent(msg.arg1, (Bundle) msg.obj); break; + case MSG_SEGMENT_RESULTS: + mInternalListener.onSegmentResults((Bundle) msg.obj); + break; + case MSG_SEGMENT_END_SESSION: + mInternalListener.onEndOfSegmentedSession(); + break; } } }; @@ -839,6 +847,14 @@ public class SpeechRecognizer { Message.obtain(mInternalHandler, MSG_RMS_CHANGED, rmsdB).sendToTarget(); } + public void onSegmentResults(final Bundle bundle) { + Message.obtain(mInternalHandler, MSG_SEGMENT_RESULTS, bundle).sendToTarget(); + } + + public void onEndOfSegmentedSession() { + Message.obtain(mInternalHandler, MSG_SEGMENT_END_SESSION).sendToTarget(); + } + public void onEvent(final int eventType, final Bundle params) { Message.obtain(mInternalHandler, MSG_ON_EVENT, eventType, eventType, params) .sendToTarget(); diff --git a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java index 21d4cbbbcca7..f4b335e42ec5 100644 --- a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java +++ b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java @@ -365,6 +365,20 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn } @Override + public void onSegmentResults(Bundle results) throws RemoteException { + mRemoteListener.onSegmentResults(results); + } + + @Override + public void onEndOfSegmentedSession() throws RemoteException { + if (DEBUG) { + Slog.i(TAG, "#onEndOfSegmentedSession invoked for a recognition session"); + } + mOnSessionComplete.run(); + mRemoteListener.onEndOfSegmentedSession(); + } + + @Override public void onEvent(int eventType, Bundle params) throws RemoteException { mRemoteListener.onEvent(eventType, params); } |