speech: Add #isOnDeviceRecognitionAvailable

Bug: 188055926
Test: CtsVoiceRecognitionTestCases
Change-Id: I6ba1d083005782beedb28313077af041af2ae975
This commit is contained in:
Andrea Ambu
2021-05-13 18:21:30 +01:00
parent 13bd292dd5
commit 40ef504bc8
2 changed files with 42 additions and 2 deletions

View File

@@ -39223,7 +39223,8 @@ package android.speech {
method @MainThread public static android.speech.SpeechRecognizer createSpeechRecognizer(android.content.Context);
method @MainThread public static android.speech.SpeechRecognizer createSpeechRecognizer(android.content.Context, android.content.ComponentName);
method public void destroy();
method public static boolean isRecognitionAvailable(android.content.Context);
method public static boolean isOnDeviceRecognitionAvailable(@NonNull android.content.Context);
method public static boolean isRecognitionAvailable(@NonNull android.content.Context);
method @MainThread public void setRecognitionListener(android.speech.RecognitionListener);
method @MainThread public void startListening(android.content.Intent);
method @MainThread public void stopListening();

View File

@@ -40,6 +40,8 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import com.android.internal.R;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -238,13 +240,45 @@ public class SpeechRecognizer {
* @param context with which {@code SpeechRecognizer} will be created
* @return {@code true} if recognition is available, {@code false} otherwise
*/
public static boolean isRecognitionAvailable(final Context context) {
public static boolean isRecognitionAvailable(@NonNull final Context context) {
// TODO(b/176578753): make sure this works well with system speech recognizers.
final List<ResolveInfo> list = context.getPackageManager().queryIntentServices(
new Intent(RecognitionService.SERVICE_INTERFACE), 0);
return list != null && list.size() != 0;
}
/**
* Checks whether an on-device speech recognition service is available on the system. If this
* method returns {@code false},
* {@link SpeechRecognizer#createOnDeviceSpeechRecognizer(Context)} will
* fail.
*
* @param context with which on-device {@code SpeechRecognizer} will be created
* @return {@code true} if on-device recognition is available, {@code false} otherwise
*/
public static boolean isOnDeviceRecognitionAvailable(@NonNull final Context context) {
ComponentName componentName =
ComponentName.unflattenFromString(
context.getString(R.string.config_defaultOnDeviceSpeechRecognitionService));
if (componentName == null) {
return false;
}
List<ResolveInfo> resolveInfos =
context.getPackageManager().queryIntentServices(
new Intent(RecognitionService.SERVICE_INTERFACE), 0);
if (resolveInfos == null) {
return false;
}
for (ResolveInfo ri : resolveInfos) {
if (ri.serviceInfo != null && componentName.equals(ri.serviceInfo.getComponentName())) {
return true;
}
}
return false;
}
/**
* Factory method to create a new {@code SpeechRecognizer}. Please note that
* {@link #setRecognitionListener(RecognitionListener)} should be called before dispatching any
@@ -315,6 +349,8 @@ public class SpeechRecognizer {
* notifications will be received.
*
* @param context in which to create {@code SpeechRecognizer}
* @throws UnsupportedOperationException iff {@link #isOnDeviceRecognitionAvailable(Context)}
* is false
* @return a new on-device {@code SpeechRecognizer}.
*/
@NonNull
@@ -324,6 +360,9 @@ public class SpeechRecognizer {
throw new IllegalArgumentException("Context cannot be null");
}
checkIsCalledFromMainThread();
if (!isOnDeviceRecognitionAvailable(context)) {
throw new UnsupportedOperationException("On-device recognition is not available");
}
return new SpeechRecognizer(context, /* onDevice */ true);
}