Merge "speech: Allow long speech sessions"

This commit is contained in:
Sergey Volnov
2022-02-07 10:36:00 +00:00
committed by Android (Google) Code Review
7 changed files with 111 additions and 1 deletions

View File

@@ -39305,6 +39305,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);
@@ -39312,6 +39313,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 {
@@ -39329,6 +39331,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();
@@ -39337,6 +39340,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 {
@@ -39392,6 +39396,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";

View File

@@ -77,6 +77,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.
*

View File

@@ -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
@@ -91,6 +98,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&lt;String&gt; 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.
*

View File

@@ -426,6 +426,26 @@ public abstract class RecognitionService extends Service {
mListener.onRmsChanged(rmsdB);
}
/**
* 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 {
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()}.

View File

@@ -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";
}

View File

@@ -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();

View File

@@ -364,6 +364,20 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn
mRemoteListener.onPartialResults(results);
}
@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);