summaryrefslogtreecommitdiffstats
path: root/core/java/android/hardware/soundtrigger
diff options
context:
space:
mode:
authorSandeep Siddhartha <sansid@google.com>2014-08-22 16:36:34 -0700
committerSandeep Siddhartha <sansid@google.com>2014-08-22 17:23:13 -0700
commitdcf3068fcb55f101680e70a8a6f84f3b2c9cb1e3 (patch)
treec1ddf18c69ab22a4ccc2d3f54b57780494dc6470 /core/java/android/hardware/soundtrigger
parent7653a30ea0232ab8323ec51ddcba8d8054ca8a2f (diff)
downloadframeworks_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.java96
-rw-r--r--core/java/android/hardware/soundtrigger/KeyphraseMetadata.java13
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);
}
}