diff options
author | Sandeep Siddhartha <sansid@google.com> | 2014-08-22 16:36:34 -0700 |
---|---|---|
committer | Sandeep Siddhartha <sansid@google.com> | 2014-08-22 17:23:13 -0700 |
commit | dcf3068fcb55f101680e70a8a6f84f3b2c9cb1e3 (patch) | |
tree | c1ddf18c69ab22a4ccc2d3f54b57780494dc6470 /core/java/android/hardware/soundtrigger | |
parent | 7653a30ea0232ab8323ec51ddcba8d8054ca8a2f (diff) | |
download | frameworks_base-dcf3068fcb55f101680e70a8a6f84f3b2c9cb1e3.zip frameworks_base-dcf3068fcb55f101680e70a8a6f84f3b2c9cb1e3.tar.gz frameworks_base-dcf3068fcb55f101680e70a8a6f84f3b2c9cb1e3.tar.bz2 |
Fix the Locale story in the hotword API
Tighten the API by taking in a locale rather than a string tag.
Tighten the checks when reading the enrollment metadata, bail out if any
attribute is missing or invalid.
Add missing recycle call for a TypedArray
Stop recognition when sound model(s) change. This is needed during
un-enrollment/re-enrollment.
Bug: 17187528
Bug: 17205230
Change-Id: Idb00b51ef8c4ea0a8f8993decea582223181fa3d
Diffstat (limited to 'core/java/android/hardware/soundtrigger')
-rw-r--r-- | core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java | 96 | ||||
-rw-r--r-- | core/java/android/hardware/soundtrigger/KeyphraseMetadata.java | 13 |
2 files changed, 72 insertions, 37 deletions
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java index 0dbde6b..2d5a271 100644 --- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java +++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java @@ -25,6 +25,8 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.service.voice.AlwaysOnHotwordDetector; +import android.text.TextUtils; +import android.util.ArraySet; import android.util.AttributeSet; import android.util.Slog; import android.util.Xml; @@ -35,6 +37,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.Locale; /** * Enrollment information about the different available keyphrases. @@ -151,33 +154,8 @@ public class KeyphraseEnrollmentInfo { TypedArray array = res.obtainAttributes(attrs, com.android.internal.R.styleable.VoiceEnrollmentApplication); - int searchKeyphraseId = array.getInt( - com.android.internal.R.styleable.VoiceEnrollmentApplication_searchKeyphraseId, - -1); - if (searchKeyphraseId != -1) { - String searchKeyphrase = array.getString(com.android.internal.R.styleable - .VoiceEnrollmentApplication_searchKeyphrase); - if (searchKeyphrase == null) { - searchKeyphrase = ""; - } - String searchKeyphraseSupportedLocales = - array.getString(com.android.internal.R.styleable - .VoiceEnrollmentApplication_searchKeyphraseSupportedLocales); - String[] supportedLocales = new String[0]; - // Get all the supported locales from the comma-delimted string. - if (searchKeyphraseSupportedLocales != null - && !searchKeyphraseSupportedLocales.isEmpty()) { - supportedLocales = searchKeyphraseSupportedLocales.split(","); - } - int recognitionModes = array.getInt(com.android.internal.R.styleable - .VoiceEnrollmentApplication_searchKeyphraseRecognitionFlags, 0); - mKeyphrases = new KeyphraseMetadata[1]; - mKeyphrases[0] = new KeyphraseMetadata( - searchKeyphraseId, searchKeyphrase, supportedLocales, recognitionModes); - } else { - mParseError = "searchKeyphraseId not specified in meta-data"; - return; - } + initializeKeyphrasesFromTypedArray(array); + array.recycle(); } catch (XmlPullParserException e) { mParseError = "Error parsing keyphrase enrollment meta-data: " + e; Slog.w(TAG, "error parsing keyphrase enrollment meta-data", e); @@ -195,6 +173,65 @@ public class KeyphraseEnrollmentInfo { } } + private void initializeKeyphrasesFromTypedArray(TypedArray array) { + // Get the keyphrase ID. + int searchKeyphraseId = array.getInt( + com.android.internal.R.styleable.VoiceEnrollmentApplication_searchKeyphraseId, -1); + if (searchKeyphraseId <= 0) { + mParseError = "No valid searchKeyphraseId specified in meta-data"; + Slog.w(TAG, mParseError); + return; + } + + // Get the keyphrase text. + String searchKeyphrase = array.getString( + com.android.internal.R.styleable.VoiceEnrollmentApplication_searchKeyphrase); + if (searchKeyphrase == null) { + mParseError = "No valid searchKeyphrase specified in meta-data"; + Slog.w(TAG, mParseError); + return; + } + + // Get the supported locales. + String searchKeyphraseSupportedLocales = array.getString( + com.android.internal.R.styleable + .VoiceEnrollmentApplication_searchKeyphraseSupportedLocales); + if (searchKeyphraseSupportedLocales == null) { + mParseError = "No valid searchKeyphraseSupportedLocales specified in meta-data"; + Slog.w(TAG, mParseError); + return; + } + ArraySet<Locale> locales = new ArraySet<>(); + // Try adding locales if the locale string is non-empty. + if (!TextUtils.isEmpty(searchKeyphraseSupportedLocales)) { + try { + String[] supportedLocalesDelimited = searchKeyphraseSupportedLocales.split(","); + for (int i = 0; i < supportedLocalesDelimited.length; i++) { + locales.add(Locale.forLanguageTag(supportedLocalesDelimited[i])); + } + } catch (Exception ex) { + // We catch a generic exception here because we don't want the system service + // to be affected by a malformed metadata because invalid locales were specified + // by the system application. + mParseError = "Error reading searchKeyphraseSupportedLocales from meta-data"; + Slog.w(TAG, mParseError, ex); + return; + } + } + + // Get the supported recognition modes. + int recognitionModes = array.getInt(com.android.internal.R.styleable + .VoiceEnrollmentApplication_searchKeyphraseRecognitionFlags, -1); + if (recognitionModes < 0) { + mParseError = "No valid searchKeyphraseRecognitionFlags specified in meta-data"; + Slog.w(TAG, mParseError); + return; + } + mKeyphrases = new KeyphraseMetadata[1]; + mKeyphrases[0] = new KeyphraseMetadata(searchKeyphraseId, searchKeyphrase, locales, + recognitionModes); + } + public String getParseError() { return mParseError; } @@ -217,11 +254,10 @@ public class KeyphraseEnrollmentInfo { * or {@link AlwaysOnHotwordDetector#MANAGE_ACTION_UN_ENROLL} * @param keyphrase The keyphrase that the user needs to be enrolled to. * @param locale The locale for which the enrollment needs to be performed. - * This is a Java locale, for example "en_US". * @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(int action, String keyphrase, String locale) { + public Intent getManageKeyphraseIntent(int action, String keyphrase, Locale locale) { if (mEnrollmentPackage == null || mEnrollmentPackage.isEmpty()) { Slog.w(TAG, "No enrollment application exists"); return null; @@ -248,7 +284,7 @@ public class KeyphraseEnrollmentInfo { * @return The metadata, if the enrollment client supports the given keyphrase * and locale, null otherwise. */ - public KeyphraseMetadata getKeyphraseMetadata(String keyphrase, String locale) { + public KeyphraseMetadata getKeyphraseMetadata(String keyphrase, Locale locale) { if (mKeyphrases == null || mKeyphrases.length == 0) { Slog.w(TAG, "Enrollment application doesn't support keyphrases"); return null; diff --git a/core/java/android/hardware/soundtrigger/KeyphraseMetadata.java b/core/java/android/hardware/soundtrigger/KeyphraseMetadata.java index 38305f9..ed8c296 100644 --- a/core/java/android/hardware/soundtrigger/KeyphraseMetadata.java +++ b/core/java/android/hardware/soundtrigger/KeyphraseMetadata.java @@ -18,6 +18,8 @@ package android.hardware.soundtrigger; import android.util.ArraySet; +import java.util.Locale; + /** * A Voice Keyphrase metadata read from the enrollment application. * @@ -26,17 +28,14 @@ import android.util.ArraySet; public class KeyphraseMetadata { public final int id; public final String keyphrase; - public final ArraySet<String> supportedLocales; + public final ArraySet<Locale> supportedLocales; public final int recognitionModeFlags; - public KeyphraseMetadata(int id, String keyphrase, String[] supportedLocales, + public KeyphraseMetadata(int id, String keyphrase, ArraySet<Locale> supportedLocales, int recognitionModeFlags) { this.id = id; this.keyphrase = keyphrase; - this.supportedLocales = new ArraySet<String>(supportedLocales.length); - for (String locale : supportedLocales) { - this.supportedLocales.add(locale); - } + this.supportedLocales = supportedLocales; this.recognitionModeFlags = recognitionModeFlags; } @@ -56,7 +55,7 @@ public class KeyphraseMetadata { /** * @return Indicates if we support the given locale. */ - public boolean supportsLocale(String locale) { + public boolean supportsLocale(Locale locale) { return supportedLocales.isEmpty() || supportedLocales.contains(locale); } } |