summaryrefslogtreecommitdiffstats
path: root/core/java/android/hardware/soundtrigger
diff options
context:
space:
mode:
authorSandeep Siddhartha <sansid@google.com>2014-07-10 19:38:18 -0700
committerSandeep Siddhartha <sansid@google.com>2014-07-15 18:36:09 -0700
commit8ecaf5f5cfd18e0436db1a27ccf46a063e9aacd7 (patch)
treeb786dc7534b41760f8330e9cecd84a6e8e65c3d5 /core/java/android/hardware/soundtrigger
parentd1f113d0f0ce5099f8efba40a88398f7945bb5e0 (diff)
downloadframeworks_base-8ecaf5f5cfd18e0436db1a27ccf46a063e9aacd7.zip
frameworks_base-8ecaf5f5cfd18e0436db1a27ccf46a063e9aacd7.tar.gz
frameworks_base-8ecaf5f5cfd18e0436db1a27ccf46a063e9aacd7.tar.bz2
Hook in startRecogniton call
Add required info to the sound model database: users & recognition modes Change-Id: I6e12cbc6342a2767c0e3d8328c0a3be899ac9952
Diffstat (limited to 'core/java/android/hardware/soundtrigger')
-rw-r--r--core/java/android/hardware/soundtrigger/Keyphrase.java40
-rw-r--r--core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java3
-rw-r--r--core/java/android/hardware/soundtrigger/KeyphraseSoundModel.java11
-rw-r--r--core/java/android/hardware/soundtrigger/SoundTriggerHelper.java122
4 files changed, 123 insertions, 53 deletions
diff --git a/core/java/android/hardware/soundtrigger/Keyphrase.java b/core/java/android/hardware/soundtrigger/Keyphrase.java
index 42fd350..51311bb 100644
--- a/core/java/android/hardware/soundtrigger/Keyphrase.java
+++ b/core/java/android/hardware/soundtrigger/Keyphrase.java
@@ -30,7 +30,11 @@ public class Keyphrase implements Parcelable {
/** A hint text to display corresponding to this keyphrase, e.g. "Hello There". */
public final String hintText;
/** The locale of interest when using this Keyphrase. */
- public String locale;
+ public final String locale;
+ /** The various recognition modes supported by this keyphrase */
+ public final int recognitionModeFlags;
+ /** The users associated with this keyphrase */
+ public final int[] users;
public static final Parcelable.Creator<Keyphrase> CREATOR
= new Parcelable.Creator<Keyphrase>() {
@@ -44,13 +48,26 @@ public class Keyphrase implements Parcelable {
};
private static Keyphrase fromParcel(Parcel in) {
- return new Keyphrase(in.readInt(), in.readString(), in.readString());
+ int id = in.readInt();
+ String hintText = in.readString();
+ String locale = in.readString();
+ int recognitionModeFlags = in.readInt();
+ int numUsers = in.readInt();
+ int[] users = null;
+ if (numUsers > 0) {
+ users = new int[numUsers];
+ in.readIntArray(users);
+ }
+ return new Keyphrase(id, hintText, locale, recognitionModeFlags, users);
}
- public Keyphrase(int id, String hintText, String locale) {
+ public Keyphrase(int id, String hintText, String locale, int recognitionModeFlags,
+ int[] users) {
this.id = id;
this.hintText = hintText;
this.locale = locale;
+ this.recognitionModeFlags = recognitionModeFlags;
+ this.users = users;
}
@Override
@@ -58,6 +75,13 @@ public class Keyphrase implements Parcelable {
dest.writeInt(id);
dest.writeString(hintText);
dest.writeString(locale);
+ dest.writeInt(recognitionModeFlags);
+ if (users != null) {
+ dest.writeInt(users.length);
+ dest.writeIntArray(users);
+ } else {
+ dest.writeInt(0);
+ }
}
@Override
@@ -98,4 +122,14 @@ public class Keyphrase implements Parcelable {
return false;
return true;
}
+
+ @Override
+ public String toString() {
+ return "Keyphrase[id=" + id + ", text=" + hintText + ", locale=" + locale
+ + ", recognitionModes=" + recognitionModeFlags + "]";
+ }
+
+ protected SoundTrigger.Keyphrase convertToSoundTriggerKeyphrase() {
+ return new SoundTrigger.Keyphrase(id, recognitionModeFlags, locale, hintText, users);
+ }
}
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
index 2f5de6a..c74134a 100644
--- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
+++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
@@ -239,7 +239,8 @@ public class KeyphraseEnrollmentInfo {
* @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 true, if an enrollment client supports the given keyphrase and the given locale.
+ * @return The metadata, if an enrollment client supports the given keyphrase
+ * and the given locale, null otherwise.
*/
public KeyphraseMetadata getKeyphraseMetadata(String keyphrase, String locale) {
if (mKeyphrases == null || mKeyphrases.length == 0) {
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseSoundModel.java b/core/java/android/hardware/soundtrigger/KeyphraseSoundModel.java
index 4ddba6a..a5ab0d2 100644
--- a/core/java/android/hardware/soundtrigger/KeyphraseSoundModel.java
+++ b/core/java/android/hardware/soundtrigger/KeyphraseSoundModel.java
@@ -65,4 +65,15 @@ public class KeyphraseSoundModel implements Parcelable {
}
dest.writeParcelableArray(keyphrases, 0);
}
+
+ public SoundTrigger.KeyphraseSoundModel convertToSoundTriggerKeyphraseSoundModel() {
+ SoundTrigger.Keyphrase[] stKeyphrases = null;
+ if (keyphrases != null) {
+ stKeyphrases = new SoundTrigger.Keyphrase[keyphrases.length];
+ for (int i = 0; i < keyphrases.length; i++) {
+ stKeyphrases[i] = keyphrases[i].convertToSoundTriggerKeyphrase();
+ }
+ }
+ return new SoundTrigger.KeyphraseSoundModel(uuid, data, stKeyphrases);
+ }
}
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerHelper.java b/core/java/android/hardware/soundtrigger/SoundTriggerHelper.java
index 0be068d..3659621 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerHelper.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerHelper.java
@@ -17,6 +17,7 @@
package android.hardware.soundtrigger;
import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
import android.util.Slog;
import android.util.SparseArray;
@@ -56,7 +57,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
private final ModuleProperties mModuleProperties;
private final SoundTriggerModule mModule;
- private final SparseArray<Listener> mListeners;
+ private final SparseArray<Listener> mActiveListeners;
private int mCurrentSoundModelHandle = INVALID_SOUND_MODEL_HANDLE;
@@ -77,7 +78,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
public SoundTriggerHelper() {
ArrayList <ModuleProperties> modules = new ArrayList<>();
int status = SoundTrigger.listModules(modules);
- mListeners = new SparseArray<>(1);
+ mActiveListeners = new SparseArray<>(1);
if (status != SoundTrigger.STATUS_OK || modules.size() == 0) {
// TODO: Figure out how to handle errors in listing the modules here.
dspInfo = null;
@@ -94,27 +95,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
}
/**
- * @return True, if the given {@link Keyphrase} is supported on DSP.
- */
- public boolean isKeyphraseSupported(Keyphrase keyphrase) {
- // TODO: We also need to look into a SoundTrigger API that let's us
- // query this. For now just return true.
- return true;
- }
-
- /**
- * @return True, if the given {@link Keyphrase} has been enrolled.
- */
- public boolean isKeyphraseEnrolled(Keyphrase keyphrase) {
- // TODO: Query VoiceInteractionManagerService
- // to list registered sound models.
- return false;
- }
-
- /**
* @return True, if a recognition for the given {@link Keyphrase} is active.
*/
- public boolean isKeyphraseActive(Keyphrase keyphrase) {
+ public synchronized boolean isKeyphraseActive(Keyphrase keyphrase) {
// TODO: Check if the recognition for the keyphrase is currently active.
return false;
}
@@ -124,55 +107,98 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
*
* @param keyphraseId The identifier of the keyphrase for which
* the recognition is to be started.
+ * @param soundModel The sound model to use for recognition.
* @param listener The listener for the recognition events related to the given keyphrase.
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
*/
- public int startRecognition(int keyphraseId, Listener listener) {
+ public synchronized int startRecognition(int keyphraseId,
+ SoundTrigger.KeyphraseSoundModel soundModel,
+ Listener listener, RecognitionConfig recognitionConfig) {
if (dspInfo == null || mModule == null) {
Slog.w(TAG, "Attempting startRecognition without the capability");
return STATUS_ERROR;
}
- if (mListeners.get(keyphraseId) != listener) {
+ Listener oldListener = mActiveListeners.get(keyphraseId);
+ if (oldListener != null && oldListener != listener) {
if (mCurrentSoundModelHandle != INVALID_SOUND_MODEL_HANDLE) {
Slog.w(TAG, "Canceling previous recognition");
// TODO: Inspect the return codes here.
mModule.unloadSoundModel(mCurrentSoundModelHandle);
}
- mListeners.get(keyphraseId).onListeningStateChanged(STATE_STOPPED);
+ mActiveListeners.get(keyphraseId).onListeningStateChanged(STATE_STOPPED);
+ mActiveListeners.remove(keyphraseId);
+ }
+
+ int[] handle = new int[] { INVALID_SOUND_MODEL_HANDLE };
+ int status = mModule.loadSoundModel(soundModel, handle);
+ if (status != SoundTrigger.STATUS_OK) {
+ Slog.w(TAG, "loadSoundModel call failed with " + status);
+ return STATUS_ERROR;
+ }
+ if (handle[0] == INVALID_SOUND_MODEL_HANDLE) {
+ Slog.w(TAG, "loadSoundModel call returned invalid sound model handle");
+ return STATUS_ERROR;
+ }
+
+ // Start the recognition.
+ status = mModule.startRecognition(handle[0], recognitionConfig);
+ if (status != SoundTrigger.STATUS_OK) {
+ Slog.w(TAG, "startRecognition failed with " + status);
+ return STATUS_ERROR;
}
+ // Everything went well!
+ mCurrentSoundModelHandle = handle[0];
// Register the new listener. This replaces the old one.
// There can only be a maximum of one active listener for a keyphrase
// at any given time.
- mListeners.put(keyphraseId, listener);
- // TODO: Get the sound model for the given keyphrase here.
- // mModule.loadSoundModel(model, soundModelHandle);
- // mModule.startRecognition(soundModelHandle, data);
- // mCurrentSoundModelHandle = soundModelHandle;
- return STATUS_ERROR;
+ mActiveListeners.put(keyphraseId, listener);
+ return STATUS_OK;
}
/**
* Stops recognition for the given {@link Keyphrase} if a recognition is currently active.
*
+ * @param keyphraseId The identifier of the keyphrase for which
+ * the recognition is to be stopped.
+ * @param listener The listener for the recognition events related to the given keyphrase.
+ *
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
*/
- public int stopRecognition(int id, Listener listener) {
+ public synchronized int stopRecognition(int keyphraseId, Listener listener) {
if (dspInfo == null || mModule == null) {
Slog.w(TAG, "Attempting stopRecognition without the capability");
return STATUS_ERROR;
}
- if (mListeners.get(id) != listener) {
+ Listener currentListener = mActiveListeners.get(keyphraseId);
+ if (currentListener == null) {
+ // startRecognition hasn't been called or it failed.
+ Slog.w(TAG, "Attempting stopRecognition without a successful startRecognition");
+ return STATUS_ERROR;
+ } else if (currentListener != listener) {
+ // TODO: Figure out if this should match the listener that was passed in during
+ // startRecognition, or should we allow a different listener to stop the recognition,
+ // in which case we don't need to pass in a listener here.
Slog.w(TAG, "Attempting stopRecognition for another recognition");
return STATUS_ERROR;
} else {
// Stop recognition if it's the current one, ignore otherwise.
// TODO: Inspect the return codes here.
- mModule.stopRecognition(mCurrentSoundModelHandle);
- mModule.unloadSoundModel(mCurrentSoundModelHandle);
+ int status = mModule.stopRecognition(mCurrentSoundModelHandle);
+ if (status != SoundTrigger.STATUS_OK) {
+ Slog.w(TAG, "stopRecognition call failed with " + status);
+ return STATUS_ERROR;
+ }
+ status = mModule.unloadSoundModel(mCurrentSoundModelHandle);
+ if (status != SoundTrigger.STATUS_OK) {
+ Slog.w(TAG, "unloadSoundModel call failed with " + status);
+ return STATUS_ERROR;
+ }
+
mCurrentSoundModelHandle = INVALID_SOUND_MODEL_HANDLE;
+ mActiveListeners.remove(keyphraseId);
return STATUS_OK;
}
}
@@ -184,28 +210,26 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// TODO: Get the keyphrase out of the event and fire events on it.
// For now, as a nasty workaround, we fire all events to the listener for
// keyphrase with TEMP_KEYPHRASE_ID.
+ Listener listener = null;
+ synchronized(this) {
+ // TODO: The keyphrase should come from the recognition event
+ // as it may be for a different keyphrase than the current one.
+ listener = mActiveListeners.get(TEMP_KEYPHRASE_ID);
+ }
+ if (listener == null) {
+ Slog.w(TAG, "received onRecognition event without any listener for it");
+ return;
+ }
switch (event.status) {
case SoundTrigger.RECOGNITION_STATUS_SUCCESS:
- // TODO: The keyphrase should come from the recognition event
- // as it may be for a different keyphrase than the current one.
- if (mListeners.get(TEMP_KEYPHRASE_ID) != null) {
- mListeners.get(TEMP_KEYPHRASE_ID).onKeyphraseSpoken();
- }
+ listener.onKeyphraseSpoken();
break;
case SoundTrigger.RECOGNITION_STATUS_ABORT:
- // TODO: The keyphrase should come from the recognition event
- // as it may be for a different keyphrase than the current one.
- if (mListeners.get(TEMP_KEYPHRASE_ID) != null) {
- mListeners.get(TEMP_KEYPHRASE_ID).onListeningStateChanged(STATE_STOPPED);
- }
+ listener.onListeningStateChanged(STATE_STOPPED);
break;
case SoundTrigger.RECOGNITION_STATUS_FAILURE:
- // TODO: The keyphrase should come from the recognition event
- // as it may be for a different keyphrase than the current one.
- if (mListeners.get(TEMP_KEYPHRASE_ID) != null) {
- mListeners.get(TEMP_KEYPHRASE_ID).onListeningStateChanged(STATE_STOPPED);
- }
+ listener.onListeningStateChanged(STATE_STOPPED);
break;
}
}