diff options
5 files changed, 134 insertions, 67 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index 8e8c8c4aa24f..8f3d0428324e 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1320,6 +1320,34 @@ package android.hardware.lights { } +package android.hardware.soundtrigger { + + public class KeyphraseEnrollmentInfo { + ctor public KeyphraseEnrollmentInfo(@NonNull android.content.pm.PackageManager); + method @Nullable public android.hardware.soundtrigger.KeyphraseMetadata getKeyphraseMetadata(@NonNull String, @NonNull java.util.Locale); + method @Nullable public android.content.Intent getManageKeyphraseIntent(int, @NonNull String, @NonNull java.util.Locale); + method @NonNull public String getParseError(); + method @NonNull public java.util.Collection<android.hardware.soundtrigger.KeyphraseMetadata> listKeyphraseMetadata(); + field public static final int MANAGE_ACTION_ENROLL = 0; // 0x0 + field public static final int MANAGE_ACTION_RE_ENROLL = 1; // 0x1 + field public static final int MANAGE_ACTION_UN_ENROLL = 2; // 0x2 + } + + public final class KeyphraseMetadata implements android.os.Parcelable { + ctor public KeyphraseMetadata(int, @NonNull String, @NonNull java.util.Set<java.util.Locale>, int); + method public int describeContents(); + method public int getId(); + method @NonNull public String getKeyphrase(); + method public int getRecognitionModeFlags(); + method @NonNull public java.util.Set<java.util.Locale> getSupportedLocales(); + method public boolean supportsLocale(@Nullable java.util.Locale); + method public boolean supportsPhrase(@Nullable String); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.KeyphraseMetadata> CREATOR; + } + +} + package android.location { public final class GnssClock implements android.os.Parcelable { diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java index 05935452e8ab..3a6d5087c260 100644 --- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java +++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java @@ -18,6 +18,9 @@ package android.hardware.soundtrigger; import android.Manifest; import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.TestApi; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -37,18 +40,22 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; /** * Enrollment information about the different available keyphrases. * * @hide */ +@TestApi public class KeyphraseEnrollmentInfo { private static final String TAG = "KeyphraseEnrollmentInfo"; /** @@ -63,6 +70,7 @@ public class KeyphraseEnrollmentInfo { * Intent Action: for managing the keyphrases for hotword detection. * This needs to be defined by a service that supports enrolling users for hotword/keyphrase * detection. + * @hide */ public static final String ACTION_MANAGE_VOICE_KEYPHRASES = "com.android.intent.action.MANAGE_VOICE_KEYPHRASES"; @@ -72,18 +80,21 @@ public class KeyphraseEnrollmentInfo { * @see #MANAGE_ACTION_ENROLL * @see #MANAGE_ACTION_RE_ENROLL * @see #MANAGE_ACTION_UN_ENROLL + * @hide */ public static final String EXTRA_VOICE_KEYPHRASE_ACTION = "com.android.intent.extra.VOICE_KEYPHRASE_ACTION"; /** * Intent extra: The hint text to be shown on the voice keyphrase management UI. + * @hide */ public static final String EXTRA_VOICE_KEYPHRASE_HINT_TEXT = "com.android.intent.extra.VOICE_KEYPHRASE_HINT_TEXT"; /** * Intent extra: The voice locale to use while managing the keyphrase. * This is a BCP-47 language tag. + * @hide */ public static final String EXTRA_VOICE_KEYPHRASE_LOCALE = "com.android.intent.extra.VOICE_KEYPHRASE_LOCALE"; @@ -125,7 +136,8 @@ public class KeyphraseEnrollmentInfo { private String mParseError; - public KeyphraseEnrollmentInfo(PackageManager pm) { + public KeyphraseEnrollmentInfo(@NonNull PackageManager pm) { + Objects.requireNonNull(pm); // Find the apps that supports enrollment for hotword keyhphrases, // Pick a privileged app and obtain the information about the supported keyphrases // from its metadata. @@ -134,13 +146,13 @@ public class KeyphraseEnrollmentInfo { if (ris == null || ris.isEmpty()) { // No application capable of enrolling for voice keyphrases is present. mParseError = "No enrollment applications found"; - mKeyphrasePackageMap = Collections.<KeyphraseMetadata, String>emptyMap(); + mKeyphrasePackageMap = Collections.emptyMap(); mKeyphrases = null; return; } - List<String> parseErrors = new LinkedList<String>(); - mKeyphrasePackageMap = new HashMap<KeyphraseMetadata, String>(); + List<String> parseErrors = new LinkedList<>(); + mKeyphrasePackageMap = new HashMap<>(); for (ResolveInfo ri : ris) { try { ApplicationInfo ai = pm.getApplicationInfo( @@ -178,7 +190,7 @@ public class KeyphraseEnrollmentInfo { mKeyphrases = null; } else { mKeyphrases = mKeyphrasePackageMap.keySet().toArray( - new KeyphraseMetadata[mKeyphrasePackageMap.size()]); + new KeyphraseMetadata[0]); } if (!parseErrors.isEmpty()) { @@ -269,8 +281,8 @@ public class KeyphraseEnrollmentInfo { if (!TextUtils.isEmpty(searchKeyphraseSupportedLocales)) { try { String[] supportedLocalesDelimited = searchKeyphraseSupportedLocales.split(","); - for (int i = 0; i < supportedLocalesDelimited.length; i++) { - locales.add(Locale.forLanguageTag(supportedLocalesDelimited[i])); + for (String s : supportedLocalesDelimited) { + locales.add(Locale.forLanguageTag(s)); } } catch (Exception ex) { // We catch a generic exception here because we don't want the system service @@ -297,6 +309,7 @@ public class KeyphraseEnrollmentInfo { return new KeyphraseMetadata(searchKeyphraseId, searchKeyphrase, locales, recognitionModes); } + @NonNull public String getParseError() { return mParseError; } @@ -305,8 +318,9 @@ public class KeyphraseEnrollmentInfo { * @return An array of available keyphrases that can be enrolled on the system. * It may be null if no keyphrases can be enrolled. */ - public KeyphraseMetadata[] listKeyphraseMetadata() { - return mKeyphrases; + @NonNull + public Collection<KeyphraseMetadata> listKeyphraseMetadata() { + return Arrays.asList(mKeyphrases); } /** @@ -319,8 +333,11 @@ public class KeyphraseEnrollmentInfo { * @return An {@link Intent} to manage the keyphrase. This can be null if managing the * given keyphrase/locale combination isn't possible. */ - public Intent getManageKeyphraseIntent(@ManageActions int action, String keyphrase, - Locale locale) { + @Nullable + public Intent getManageKeyphraseIntent(@ManageActions int action, @NonNull String keyphrase, + @NonNull Locale locale) { + Objects.requireNonNull(keyphrase); + Objects.requireNonNull(locale); if (mKeyphrasePackageMap == null || mKeyphrasePackageMap.isEmpty()) { Slog.w(TAG, "No enrollment application exists"); return null; @@ -328,12 +345,11 @@ public class KeyphraseEnrollmentInfo { KeyphraseMetadata keyphraseMetadata = getKeyphraseMetadata(keyphrase, locale); if (keyphraseMetadata != null) { - Intent intent = new Intent(ACTION_MANAGE_VOICE_KEYPHRASES) + return new Intent(ACTION_MANAGE_VOICE_KEYPHRASES) .setPackage(mKeyphrasePackageMap.get(keyphraseMetadata)) .putExtra(EXTRA_VOICE_KEYPHRASE_HINT_TEXT, keyphrase) .putExtra(EXTRA_VOICE_KEYPHRASE_LOCALE, locale.toLanguageTag()) .putExtra(EXTRA_VOICE_KEYPHRASE_ACTION, action); - return intent; } return null; } @@ -348,7 +364,11 @@ public class KeyphraseEnrollmentInfo { * @return The metadata, if the enrollment client supports the given keyphrase * and locale, null otherwise. */ - public KeyphraseMetadata getKeyphraseMetadata(String keyphrase, Locale locale) { + @Nullable + public KeyphraseMetadata getKeyphraseMetadata(@NonNull String keyphrase, + @NonNull Locale locale) { + Objects.requireNonNull(keyphrase); + Objects.requireNonNull(locale); if (mKeyphrases != null && mKeyphrases.length > 0) { for (KeyphraseMetadata keyphraseMetadata : mKeyphrases) { // Check if the given keyphrase is supported in the locale provided by diff --git a/core/java/android/hardware/soundtrigger/KeyphraseMetadata.java b/core/java/android/hardware/soundtrigger/KeyphraseMetadata.java index 15462deea158..aa86368830cc 100644 --- a/core/java/android/hardware/soundtrigger/KeyphraseMetadata.java +++ b/core/java/android/hardware/soundtrigger/KeyphraseMetadata.java @@ -18,57 +18,78 @@ package android.hardware.soundtrigger; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.os.Parcelable; import android.util.ArraySet; import com.android.internal.util.DataClass; import java.util.Locale; +import java.util.Set; /** * A Voice Keyphrase metadata read from the enrollment application. * * @hide */ +@TestApi @DataClass( genEqualsHashCode = true, genToString = true, genConstructor = false, genHiddenConstDefs = true) public final class KeyphraseMetadata implements Parcelable { - public final int id; + private final int mId; @NonNull - public final String keyphrase; + private final String mKeyphrase; @NonNull - public final ArraySet<Locale> supportedLocales; - public final int recognitionModeFlags; + private final ArraySet<Locale> mSupportedLocales; + private final int mRecognitionModeFlags; public KeyphraseMetadata(int id, @NonNull String keyphrase, - @NonNull ArraySet<Locale> supportedLocales, int recognitionModeFlags) { - this.id = id; - this.keyphrase = keyphrase; - this.supportedLocales = supportedLocales; - this.recognitionModeFlags = recognitionModeFlags; + @NonNull Set<Locale> supportedLocales, int recognitionModeFlags) { + this.mId = id; + this.mKeyphrase = keyphrase; + this.mSupportedLocales = new ArraySet<>(supportedLocales); + this.mRecognitionModeFlags = recognitionModeFlags; + } + + public int getId() { + return mId; + } + + @NonNull + public String getKeyphrase() { + return mKeyphrase; + } + + @NonNull + public Set<Locale> getSupportedLocales() { + return mSupportedLocales; + } + + public int getRecognitionModeFlags() { + return mRecognitionModeFlags; } /** * @return Indicates if we support the given phrase. */ public boolean supportsPhrase(@Nullable String phrase) { - return keyphrase.isEmpty() || keyphrase.equalsIgnoreCase(phrase); + return getKeyphrase().isEmpty() || getKeyphrase().equalsIgnoreCase(phrase); } /** * @return Indicates if we support the given locale. */ public boolean supportsLocale(@Nullable Locale locale) { - return supportedLocales.isEmpty() || supportedLocales.contains(locale); + return getSupportedLocales().isEmpty() || getSupportedLocales().contains(locale); } - // Code below generated by codegen v1.0.14. + // Code below generated by codegen v1.0.15. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -88,10 +109,10 @@ public final class KeyphraseMetadata implements Parcelable { // String fieldNameToString() { ... } return "KeyphraseMetadata { " + - "id = " + id + ", " + - "keyphrase = " + keyphrase + ", " + - "supportedLocales = " + supportedLocales + ", " + - "recognitionModeFlags = " + recognitionModeFlags + + "id = " + mId + ", " + + "keyphrase = " + mKeyphrase + ", " + + "supportedLocales = " + mSupportedLocales + ", " + + "recognitionModeFlags = " + mRecognitionModeFlags + " }"; } @@ -108,10 +129,10 @@ public final class KeyphraseMetadata implements Parcelable { KeyphraseMetadata that = (KeyphraseMetadata) o; //noinspection PointlessBooleanExpression return true - && id == that.id - && java.util.Objects.equals(keyphrase, that.keyphrase) - && java.util.Objects.equals(supportedLocales, that.supportedLocales) - && recognitionModeFlags == that.recognitionModeFlags; + && mId == that.mId + && java.util.Objects.equals(mKeyphrase, that.mKeyphrase) + && java.util.Objects.equals(mSupportedLocales, that.mSupportedLocales) + && mRecognitionModeFlags == that.mRecognitionModeFlags; } @Override @@ -121,10 +142,10 @@ public final class KeyphraseMetadata implements Parcelable { // int fieldNameHashCode() { ... } int _hash = 1; - _hash = 31 * _hash + id; - _hash = 31 * _hash + java.util.Objects.hashCode(keyphrase); - _hash = 31 * _hash + java.util.Objects.hashCode(supportedLocales); - _hash = 31 * _hash + recognitionModeFlags; + _hash = 31 * _hash + mId; + _hash = 31 * _hash + java.util.Objects.hashCode(mKeyphrase); + _hash = 31 * _hash + java.util.Objects.hashCode(mSupportedLocales); + _hash = 31 * _hash + mRecognitionModeFlags; return _hash; } @@ -134,10 +155,10 @@ public final class KeyphraseMetadata implements Parcelable { // You can override field parcelling by defining methods like: // void parcelFieldName(Parcel dest, int flags) { ... } - dest.writeInt(id); - dest.writeString(keyphrase); - dest.writeArraySet(supportedLocales); - dest.writeInt(recognitionModeFlags); + dest.writeInt(mId); + dest.writeString(mKeyphrase); + dest.writeArraySet(mSupportedLocales); + dest.writeInt(mRecognitionModeFlags); } @Override @@ -151,19 +172,19 @@ public final class KeyphraseMetadata implements Parcelable { // You can override field unparcelling by defining methods like: // static FieldType unparcelFieldName(Parcel in) { ... } - int _id = in.readInt(); - String _keyphrase = in.readString(); - ArraySet<Locale> _supportedLocales = (ArraySet) in.readArraySet(null); - int _recognitionModeFlags = in.readInt(); + int id = in.readInt(); + String keyphrase = in.readString(); + ArraySet<Locale> supportedLocales = (ArraySet) in.readArraySet(null); + int recognitionModeFlags = in.readInt(); - this.id = _id; - this.keyphrase = _keyphrase; + this.mId = id; + this.mKeyphrase = keyphrase; com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, keyphrase); - this.supportedLocales = _supportedLocales; + NonNull.class, null, mKeyphrase); + this.mSupportedLocales = supportedLocales; com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, supportedLocales); - this.recognitionModeFlags = _recognitionModeFlags; + NonNull.class, null, mSupportedLocales); + this.mRecognitionModeFlags = recognitionModeFlags; // onConstructed(); // You can define this method to get a callback } @@ -183,10 +204,10 @@ public final class KeyphraseMetadata implements Parcelable { }; @DataClass.Generated( - time = 1579290593964L, - codegenVersion = "1.0.14", + time = 1586191622057L, + codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/hardware/soundtrigger/KeyphraseMetadata.java", - inputSignatures = "public final int id\npublic final @android.annotation.NonNull java.lang.String keyphrase\npublic final @android.annotation.NonNull android.util.ArraySet<java.util.Locale> supportedLocales\npublic final int recognitionModeFlags\npublic boolean supportsPhrase(java.lang.String)\npublic boolean supportsLocale(java.util.Locale)\nclass KeyphraseMetadata extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genConstructor=false, genHiddenConstDefs=true)") + inputSignatures = "private final int mId\nprivate final @android.annotation.NonNull java.lang.String mKeyphrase\nprivate final @android.annotation.NonNull android.util.ArraySet<java.util.Locale> mSupportedLocales\nprivate final int mRecognitionModeFlags\npublic int getId()\npublic @android.annotation.NonNull java.lang.String getKeyphrase()\npublic @android.annotation.NonNull java.util.Set<java.util.Locale> getSupportedLocales()\npublic int getRecognitionModeFlags()\npublic boolean supportsPhrase(java.lang.String)\npublic boolean supportsLocale(java.util.Locale)\nclass KeyphraseMetadata extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genConstructor=false, genHiddenConstDefs=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index 97cd7608f876..6f941121771e 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -460,7 +460,7 @@ public class AlwaysOnHotwordDetector { "Getting supported recognition modes for the keyphrase is not supported"); } - return mKeyphraseMetadata.recognitionModeFlags; + return mKeyphraseMetadata.getRecognitionModeFlags(); } /** @@ -765,8 +765,8 @@ public class AlwaysOnHotwordDetector { private int startRecognitionLocked(int recognitionFlags) { KeyphraseRecognitionExtra[] recognitionExtra = new KeyphraseRecognitionExtra[1]; // TODO: Do we need to do something about the confidence level here? - recognitionExtra[0] = new KeyphraseRecognitionExtra(mKeyphraseMetadata.id, - mKeyphraseMetadata.recognitionModeFlags, 0, new ConfidenceLevel[0]); + recognitionExtra[0] = new KeyphraseRecognitionExtra(mKeyphraseMetadata.getId(), + mKeyphraseMetadata.getRecognitionModeFlags(), 0, new ConfidenceLevel[0]); boolean captureTriggerAudio = (recognitionFlags&RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO) != 0; boolean allowMultipleTriggers = @@ -783,7 +783,7 @@ public class AlwaysOnHotwordDetector { int code; try { code = mModelManagementService.startRecognition( - mKeyphraseMetadata.id, mLocale.toLanguageTag(), mInternalCallback, + mKeyphraseMetadata.getId(), mLocale.toLanguageTag(), mInternalCallback, new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers, recognitionExtra, null /* additional data */, audioCapabilities)); } catch (RemoteException e) { @@ -799,7 +799,7 @@ public class AlwaysOnHotwordDetector { private int stopRecognitionLocked() { int code; try { - code = mModelManagementService.stopRecognition(mKeyphraseMetadata.id, + code = mModelManagementService.stopRecognition(mKeyphraseMetadata.getId(), mInternalCallback); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -813,7 +813,7 @@ public class AlwaysOnHotwordDetector { private int setParameterLocked(@ModelParams int modelParam, int value) { try { - int code = mModelManagementService.setParameter(mKeyphraseMetadata.id, modelParam, + int code = mModelManagementService.setParameter(mKeyphraseMetadata.getId(), modelParam, value); if (code != STATUS_OK) { @@ -828,7 +828,7 @@ public class AlwaysOnHotwordDetector { private int getParameterLocked(@ModelParams int modelParam) { try { - return mModelManagementService.getParameter(mKeyphraseMetadata.id, modelParam); + return mModelManagementService.getParameter(mKeyphraseMetadata.getId(), modelParam); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -838,7 +838,7 @@ public class AlwaysOnHotwordDetector { private ModelParamRange queryParameterLocked(@ModelParams int modelParam) { try { SoundTrigger.ModelParamRange modelParamRange = - mModelManagementService.queryParameter(mKeyphraseMetadata.id, modelParam); + mModelManagementService.queryParameter(mKeyphraseMetadata.getId(), modelParam); if (modelParamRange == null) { return null; diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java index f1dd1de0e517..b7f5b15f72ac 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java @@ -16,14 +16,11 @@ package com.android.test.voiceinteraction; -import android.content.ComponentName; import android.content.Intent; -import android.os.Bundle; import android.service.voice.AlwaysOnHotwordDetector; import android.service.voice.AlwaysOnHotwordDetector.Callback; import android.service.voice.AlwaysOnHotwordDetector.EventPayload; import android.service.voice.VoiceInteractionService; -import android.service.voice.VoiceInteractionSession; import android.util.Log; import java.util.Arrays; @@ -68,7 +65,8 @@ public class MainInteractionService extends VoiceInteractionService { Log.i(TAG, "Creating " + this); Log.i(TAG, "Keyphrase enrollment error? " + getKeyphraseEnrollmentInfo().getParseError()); Log.i(TAG, "Keyphrase enrollment meta-data: " - + Arrays.toString(getKeyphraseEnrollmentInfo().listKeyphraseMetadata())); + + Arrays.toString(getKeyphraseEnrollmentInfo().listKeyphraseMetadata().toArray( + new android.hardware.soundtrigger.KeyphraseMetadata[0]))); mHotwordDetector = createAlwaysOnHotwordDetector( "Hello There", Locale.forLanguageTag("en-US"), mHotwordCallback); |