Merge "Initial code for listing/storing sound models"

This commit is contained in:
Sandeep Siddhartha
2014-07-08 18:44:34 +00:00
committed by Android (Google) Code Review
3 changed files with 288 additions and 73 deletions

View File

@@ -16,8 +16,6 @@
package android.hardware.soundtrigger;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import java.util.ArrayList;
@@ -65,7 +63,7 @@ public class SoundTrigger {
public final int maxSoundModels;
/** Maximum number of key phrases */
public final int maxKeyPhrases;
public final int maxKeyphrases;
/** Maximum number of users per key phrase */
public final int maxUsers;
@@ -86,7 +84,7 @@ public class SoundTrigger {
public final int powerConsumptionMw;
ModuleProperties(int id, String implementor, String description,
String uuid, int version, int maxSoundModels, int maxKeyPhrases,
String uuid, int version, int maxSoundModels, int maxKeyphrases,
int maxUsers, int recognitionModes, boolean supportsCaptureTransition,
int maxBufferMs, boolean supportsConcurrentCapture,
int powerConsumptionMw) {
@@ -96,7 +94,7 @@ public class SoundTrigger {
this.uuid = UUID.fromString(uuid);
this.version = version;
this.maxSoundModels = maxSoundModels;
this.maxKeyPhrases = maxKeyPhrases;
this.maxKeyphrases = maxKeyphrases;
this.maxUsers = maxUsers;
this.recognitionModes = recognitionModes;
this.supportsCaptureTransition = supportsCaptureTransition;
@@ -109,7 +107,7 @@ public class SoundTrigger {
/*****************************************************************************
* A SoundModel describes the attributes and contains the binary data used by the hardware
* implementation to detect a particular sound pattern.
* A specialized version {@link KeyPhraseSoundModel} is defined for key phrase
* A specialized version {@link KeyphraseSoundModel} is defined for key phrase
* sound models.
****************************************************************************/
public static class SoundModel {
@@ -119,23 +117,30 @@ public class SoundTrigger {
/** Keyphrase sound model */
public static final int TYPE_KEYPHRASE = 0;
/** Unique sound model identifier */
public final UUID uuid;
/** Sound model type (e.g. TYPE_KEYPHRASE); */
public final int type;
/** Opaque data. For use by vendor implementation and enrollment application */
public final byte[] data;
public SoundModel(int type, byte[] data) {
public SoundModel(UUID uuid, int type, byte[] data) {
this.uuid = uuid;
this.type = type;
this.data = data;
}
}
/*****************************************************************************
* A KeyPhrase describes a key phrase that can be detected by a
* {@link KeyPhraseSoundModel}
* A Keyphrase describes a key phrase that can be detected by a
* {@link KeyphraseSoundModel}
****************************************************************************/
public static class KeyPhrase {
public static class Keyphrase {
/** Unique identifier for this keyphrase */
public final int id;
/** Recognition modes supported for this key phrase in the model */
public final int recognitionModes;
@@ -148,7 +153,8 @@ public class SoundTrigger {
/** Number of users this key phrase has been trained for */
public final int numUsers;
public KeyPhrase(int recognitionModes, String locale, String text, int numUsers) {
public Keyphrase(int id, int recognitionModes, String locale, String text, int numUsers) {
this.id = id;
this.recognitionModes = recognitionModes;
this.locale = locale;
this.text = text;
@@ -157,17 +163,17 @@ public class SoundTrigger {
}
/*****************************************************************************
* A KeyPhraseSoundModel is a specialized {@link SoundModel} for key phrases.
* A KeyphraseSoundModel is a specialized {@link SoundModel} for key phrases.
* It contains data needed by the hardware to detect a certain number of key phrases
* and the list of corresponding {@link KeyPhrase} descriptors.
* and the list of corresponding {@link Keyphrase} descriptors.
****************************************************************************/
public static class KeyPhraseSoundModel extends SoundModel {
public static class KeyphraseSoundModel extends SoundModel {
/** Key phrases in this sound model */
public final KeyPhrase[] keyPhrases; // keyword phrases in model
public final Keyphrase[] keyphrases; // keyword phrases in model
public KeyPhraseSoundModel(byte[] data, KeyPhrase[] keyPhrases) {
super(TYPE_KEYPHRASE, data);
this.keyPhrases = keyPhrases;
public KeyphraseSoundModel(UUID id, byte[] data, Keyphrase[] keyphrases) {
super(id, TYPE_KEYPHRASE, data);
this.keyphrases = keyphrases;
}
}
@@ -225,10 +231,10 @@ public class SoundTrigger {
}
/**
* Additional data conveyed by a {@link KeyPhraseRecognitionEvent}
* Additional data conveyed by a {@link KeyphraseRecognitionEvent}
* for a key phrase detection.
*/
public static class KeyPhraseRecognitionExtra {
public static class KeyphraseRecognitionExtra {
/** Confidence level for each user defined in the key phrase in the same order as
* users in the key phrase. The confidence level is expressed in percentage (0% -100%) */
public final int[] confidenceLevels;
@@ -236,7 +242,7 @@ public class SoundTrigger {
/** Recognition modes matched for this event */
public final int recognitionModes;
KeyPhraseRecognitionExtra(int[] confidenceLevels, int recognitionModes) {
KeyphraseRecognitionExtra(int[] confidenceLevels, int recognitionModes) {
this.confidenceLevels = confidenceLevels;
this.recognitionModes = recognitionModes;
}
@@ -245,19 +251,19 @@ public class SoundTrigger {
/**
* Specialized {@link RecognitionEvent} for a key phrase detection.
*/
public static class KeyPhraseRecognitionEvent extends RecognitionEvent {
public static class KeyphraseRecognitionEvent extends RecognitionEvent {
/** Indicates if the key phrase is present in the buffered audio available for capture */
public final KeyPhraseRecognitionExtra[] keyPhraseExtras;
public final KeyphraseRecognitionExtra[] keyphraseExtras;
/** Additional data available for each recognized key phrases in the model */
public final boolean keyPhraseInCapture;
public final boolean keyphraseInCapture;
KeyPhraseRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
KeyphraseRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
int captureSession, int captureDelayMs, byte[] data,
boolean keyPhraseInCapture, KeyPhraseRecognitionExtra[] keyPhraseExtras) {
boolean keyphraseInCapture, KeyphraseRecognitionExtra[] keyphraseExtras) {
super(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs, data);
this.keyPhraseInCapture = keyPhraseInCapture;
this.keyPhraseExtras = keyPhraseExtras;
this.keyphraseInCapture = keyphraseInCapture;
this.keyphraseExtras = keyphraseExtras;
}
}

View File

@@ -37,6 +37,11 @@ static struct {
jmethodID add;
} gArrayListMethods;
static jclass gUUIDClass;
static struct {
jmethodID toString;
} gUUIDMethods;
static const char* const kSoundTriggerClassPathName = "android/hardware/soundtrigger/SoundTrigger";
static jclass gSoundTriggerClass;
@@ -57,25 +62,27 @@ static const char* const kSoundModelClassPathName =
"android/hardware/soundtrigger/SoundTrigger$SoundModel";
static jclass gSoundModelClass;
static struct {
jfieldID uuid;
jfieldID data;
} gSoundModelFields;
static const char* const kKeyPhraseClassPathName =
"android/hardware/soundtrigger/SoundTrigger$KeyPhrase";
static jclass gKeyPhraseClass;
static const char* const kKeyphraseClassPathName =
"android/hardware/soundtrigger/SoundTrigger$Keyphrase";
static jclass gKeyphraseClass;
static struct {
jfieldID id;
jfieldID recognitionModes;
jfieldID locale;
jfieldID text;
jfieldID numUsers;
} gKeyPhraseFields;
} gKeyphraseFields;
static const char* const kKeyPhraseSoundModelClassPathName =
"android/hardware/soundtrigger/SoundTrigger$KeyPhraseSoundModel";
static jclass gKeyPhraseSoundModelClass;
static const char* const kKeyphraseSoundModelClassPathName =
"android/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel";
static jclass gKeyphraseSoundModelClass;
static struct {
jfieldID keyPhrases;
} gKeyPhraseSoundModelFields;
jfieldID keyphrases;
} gKeyphraseSoundModelFields;
static const char* const kRecognitionEventClassPathName =
@@ -83,15 +90,15 @@ static const char* const kRecognitionEventClassPathName =
static jclass gRecognitionEventClass;
static jmethodID gRecognitionEventCstor;
static const char* const kKeyPhraseRecognitionEventClassPathName =
"android/hardware/soundtrigger/SoundTrigger$KeyPhraseRecognitionEvent";
static jclass gKeyPhraseRecognitionEventClass;
static jmethodID gKeyPhraseRecognitionEventCstor;
static const char* const kKeyphraseRecognitionEventClassPathName =
"android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent";
static jclass gKeyphraseRecognitionEventClass;
static jmethodID gKeyphraseRecognitionEventCstor;
static const char* const kKeyPhraseRecognitionExtraClassPathName =
"android/hardware/soundtrigger/SoundTrigger$KeyPhraseRecognitionExtra";
static jclass gKeyPhraseRecognitionExtraClass;
static jmethodID gKeyPhraseRecognitionExtraCstor;
static const char* const kKeyphraseRecognitionExtraClassPathName =
"android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra";
static jclass gKeyphraseRecognitionExtraClass;
static jmethodID gKeyphraseRecognitionExtraCstor;
static Mutex gLock;
@@ -170,7 +177,7 @@ void JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognitio
(struct sound_trigger_phrase_recognition_event *)event;
jobjectArray jExtras = env->NewObjectArray(phraseEvent->num_phrases,
gKeyPhraseRecognitionExtraClass, NULL);
gKeyphraseRecognitionExtraClass, NULL);
if (jExtras == NULL) {
return;
}
@@ -185,8 +192,8 @@ void JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognitio
phraseEvent->phrase_extras[i].confidence_levels,
phraseEvent->phrase_extras[i].num_users * sizeof(int));
env->ReleaseIntArrayElements(jConfidenceLevels, nConfidenceLevels, 0);
jobject jNewExtra = env->NewObject(gKeyPhraseRecognitionExtraClass,
gKeyPhraseRecognitionExtraCstor,
jobject jNewExtra = env->NewObject(gKeyphraseRecognitionExtraClass,
gKeyphraseRecognitionExtraCstor,
jConfidenceLevels,
phraseEvent->phrase_extras[i].recognition_modes);
@@ -196,7 +203,7 @@ void JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognitio
env->SetObjectArrayElement(jExtras, i, jNewExtra);
}
jEvent = env->NewObject(gKeyPhraseRecognitionEventClass, gKeyPhraseRecognitionEventCstor,
jEvent = env->NewObject(gKeyphraseRecognitionEventClass, gKeyphraseRecognitionEventCstor,
event->status, event->model, event->capture_available,
event->capture_session, event->capture_delay_ms, jData,
phraseEvent->key_phrase_in_capture, jExtras);
@@ -381,6 +388,9 @@ android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
sp<IMemory> memory;
size_t size;
sound_model_handle_t handle;
jobject jUuid;
jstring jUuidString;
const char *nUuidString;
ALOGV("loadSoundModel");
sp<SoundTrigger> module = getSoundTrigger(env, thiz);
@@ -404,13 +414,22 @@ android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
}
size_t offset;
sound_trigger_sound_model_type_t type;
if (env->IsInstanceOf(jSoundModel, gKeyPhraseSoundModelClass)) {
if (env->IsInstanceOf(jSoundModel, gKeyphraseSoundModelClass)) {
offset = sizeof(struct sound_trigger_phrase_sound_model);
type = SOUND_MODEL_TYPE_KEYPHRASE;
} else {
offset = sizeof(struct sound_trigger_sound_model);
type = SOUND_MODEL_TYPE_UNKNOWN;
}
jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.uuid);
jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
nUuidString = env->GetStringUTFChars(jUuidString, NULL);
sound_trigger_uuid_t nUuid;
SoundTrigger::stringToGuid(nUuidString, &nUuid);
env->ReleaseStringUTFChars(jUuidString, nUuidString);
env->DeleteLocalRef(jUuidString);
jData = (jbyteArray)env->GetObjectField(jSoundModel, gSoundModelFields.data);
if (jData == NULL) {
status = SOUNDTRIGGER_STATUS_BAD_VALUE;
@@ -438,6 +457,7 @@ android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
nSoundModel = (struct sound_trigger_sound_model *)memory->pointer();
nSoundModel->type = type;
nSoundModel->uuid = nUuid;
nSoundModel->data_size = size;
nSoundModel->data_offset = offset;
memcpy((char *)nSoundModel + offset, nData, size);
@@ -446,7 +466,7 @@ android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
(struct sound_trigger_phrase_sound_model *)nSoundModel;
jobjectArray jPhrases =
(jobjectArray)env->GetObjectField(jSoundModel, gKeyPhraseSoundModelFields.keyPhrases);
(jobjectArray)env->GetObjectField(jSoundModel, gKeyphraseSoundModelFields.keyphrases);
if (jPhrases == NULL) {
status = SOUNDTRIGGER_STATUS_BAD_VALUE;
goto exit;
@@ -457,16 +477,18 @@ android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
ALOGV("loadSoundModel numPhrases %d", numPhrases);
for (size_t i = 0; i < numPhrases; i++) {
jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
phraseModel->phrases[i].id =
env->GetIntField(jPhrase,gKeyphraseFields.id);
phraseModel->phrases[i].recognition_mode =
env->GetIntField(jPhrase,gKeyPhraseFields.recognitionModes);
env->GetIntField(jPhrase,gKeyphraseFields.recognitionModes);
phraseModel->phrases[i].num_users =
env->GetIntField(jPhrase, gKeyPhraseFields.numUsers);
jstring jLocale = (jstring)env->GetObjectField(jPhrase, gKeyPhraseFields.locale);
env->GetIntField(jPhrase, gKeyphraseFields.numUsers);
jstring jLocale = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.locale);
const char *nLocale = env->GetStringUTFChars(jLocale, NULL);
strncpy(phraseModel->phrases[i].locale,
nLocale,
SOUND_TRIGGER_MAX_LOCALE_LEN);
jstring jText = (jstring)env->GetObjectField(jPhrase, gKeyPhraseFields.text);
jstring jText = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.text);
const char *nText = env->GetStringUTFChars(jText, NULL);
strncpy(phraseModel->phrases[i].text,
nText,
@@ -599,6 +621,10 @@ int register_android_hardware_SoundTrigger(JNIEnv *env)
gArrayListClass = (jclass) env->NewGlobalRef(arrayListClass);
gArrayListMethods.add = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
jclass uuidClass = env->FindClass("java/util/UUID");
gUUIDClass = (jclass) env->NewGlobalRef(uuidClass);
gUUIDMethods.toString = env->GetMethodID(uuidClass, "toString", "()Ljava/lang/String;");
jclass lClass = env->FindClass(kSoundTriggerClassPathName);
gSoundTriggerClass = (jclass) env->NewGlobalRef(lClass);
@@ -617,20 +643,22 @@ int register_android_hardware_SoundTrigger(JNIEnv *env)
jclass soundModelClass = env->FindClass(kSoundModelClassPathName);
gSoundModelClass = (jclass) env->NewGlobalRef(soundModelClass);
gSoundModelFields.uuid = env->GetFieldID(soundModelClass, "uuid", "Ljava/util/UUID;");
gSoundModelFields.data = env->GetFieldID(soundModelClass, "data", "[B");
jclass keyPhraseClass = env->FindClass(kKeyPhraseClassPathName);
gKeyPhraseClass = (jclass) env->NewGlobalRef(keyPhraseClass);
gKeyPhraseFields.recognitionModes = env->GetFieldID(keyPhraseClass, "recognitionModes", "I");
gKeyPhraseFields.locale = env->GetFieldID(keyPhraseClass, "locale", "Ljava/lang/String;");
gKeyPhraseFields.text = env->GetFieldID(keyPhraseClass, "text", "Ljava/lang/String;");
gKeyPhraseFields.numUsers = env->GetFieldID(keyPhraseClass, "numUsers", "I");
jclass keyphraseClass = env->FindClass(kKeyphraseClassPathName);
gKeyphraseClass = (jclass) env->NewGlobalRef(keyphraseClass);
gKeyphraseFields.id = env->GetFieldID(keyphraseClass, "id", "I");
gKeyphraseFields.recognitionModes = env->GetFieldID(keyphraseClass, "recognitionModes", "I");
gKeyphraseFields.locale = env->GetFieldID(keyphraseClass, "locale", "Ljava/lang/String;");
gKeyphraseFields.text = env->GetFieldID(keyphraseClass, "text", "Ljava/lang/String;");
gKeyphraseFields.numUsers = env->GetFieldID(keyphraseClass, "numUsers", "I");
jclass keyPhraseSoundModelClass = env->FindClass(kKeyPhraseSoundModelClassPathName);
gKeyPhraseSoundModelClass = (jclass) env->NewGlobalRef(keyPhraseSoundModelClass);
gKeyPhraseSoundModelFields.keyPhrases = env->GetFieldID(keyPhraseSoundModelClass,
"keyPhrases",
"[Landroid/hardware/soundtrigger/SoundTrigger$KeyPhrase;");
jclass keyphraseSoundModelClass = env->FindClass(kKeyphraseSoundModelClassPathName);
gKeyphraseSoundModelClass = (jclass) env->NewGlobalRef(keyphraseSoundModelClass);
gKeyphraseSoundModelFields.keyphrases = env->GetFieldID(keyphraseSoundModelClass,
"keyphrases",
"[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;");
jclass recognitionEventClass = env->FindClass(kRecognitionEventClassPathName);
@@ -638,15 +666,15 @@ int register_android_hardware_SoundTrigger(JNIEnv *env)
gRecognitionEventCstor = env->GetMethodID(recognitionEventClass, "<init>",
"(IIZII[B)V");
jclass keyPhraseRecognitionEventClass = env->FindClass(kKeyPhraseRecognitionEventClassPathName);
gKeyPhraseRecognitionEventClass = (jclass) env->NewGlobalRef(keyPhraseRecognitionEventClass);
gKeyPhraseRecognitionEventCstor = env->GetMethodID(keyPhraseRecognitionEventClass, "<init>",
"(IIZII[BZ[Landroid/hardware/soundtrigger/SoundTrigger$KeyPhraseRecognitionExtra;)V");
jclass keyphraseRecognitionEventClass = env->FindClass(kKeyphraseRecognitionEventClassPathName);
gKeyphraseRecognitionEventClass = (jclass) env->NewGlobalRef(keyphraseRecognitionEventClass);
gKeyphraseRecognitionEventCstor = env->GetMethodID(keyphraseRecognitionEventClass, "<init>",
"(IIZII[BZ[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V");
jclass keyPhraseRecognitionExtraClass = env->FindClass(kKeyPhraseRecognitionExtraClassPathName);
gKeyPhraseRecognitionExtraClass = (jclass) env->NewGlobalRef(keyPhraseRecognitionExtraClass);
gKeyPhraseRecognitionExtraCstor = env->GetMethodID(keyPhraseRecognitionExtraClass, "<init>",
jclass keyphraseRecognitionExtraClass = env->FindClass(kKeyphraseRecognitionExtraClassPathName);
gKeyphraseRecognitionExtraClass = (jclass) env->NewGlobalRef(keyphraseRecognitionExtraClass);
gKeyphraseRecognitionExtraCstor = env->GetMethodID(keyphraseRecognitionExtraClass, "<init>",
"([II)V");
int status = AndroidRuntime::registerNativeMethods(env,

View File

@@ -0,0 +1,181 @@
/**
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.voiceinteraction;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.hardware.soundtrigger.SoundTrigger;
import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
import android.util.Slog;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @hide
*/
public class DatabaseHelper extends SQLiteOpenHelper {
static final String TAG = "SoundModelDBHelper";
private static final String NAME = "sound_model.db";
private static final int VERSION = 1;
public static interface KeyphraseContract {
public static final String TABLE = "keyphrase";
public static final String KEY_ID = "_id";
public static final String KEY_RECOGNITION_MODES = "modes";
public static final String KEY_LOCALE = "locale";
public static final String KEY_HINT_TEXT = "hint_text";
public static final String KEY_NUM_USERS = "num_users";
public static final String KEY_SOUND_MODEL_ID = "sound_model_id";
}
public static interface SoundModelContract {
public static final String TABLE = "sound_model";
public static final String KEY_ID = "_id";
public static final String KEY_TYPE = "type";
public static final String KEY_DATA = "data";
}
// Table Create Statements
private static final String CREATE_TABLE_KEYPRHASES = "CREATE TABLE "
+ KeyphraseContract.TABLE + "("
+ KeyphraseContract.KEY_ID + " INTEGER PRIMARY KEY,"
+ KeyphraseContract.KEY_RECOGNITION_MODES + " INTEGER,"
+ KeyphraseContract.KEY_NUM_USERS + " INTEGER,"
+ KeyphraseContract.KEY_SOUND_MODEL_ID + " TEXT,"
+ KeyphraseContract.KEY_LOCALE + " TEXT,"
+ KeyphraseContract.KEY_HINT_TEXT + " TEXT" + ")";
private static final String CREATE_TABLE_SOUND_MODEL = "CREATE TABLE "
+ SoundModelContract.TABLE + "("
+ SoundModelContract.KEY_ID + " TEXT PRIMARY KEY,"
+ SoundModelContract.KEY_TYPE + " INTEGER,"
+ SoundModelContract.KEY_DATA + " BLOB" + ")";
public DatabaseHelper(Context context, CursorFactory factory) {
super(context, NAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// creating required tables
db.execSQL(CREATE_TABLE_KEYPRHASES);
db.execSQL(CREATE_TABLE_SOUND_MODEL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO(sansid): For now, drop older tables and recreate new ones.
db.execSQL("DROP TABLE IF EXISTS " + KeyphraseContract.TABLE);
db.execSQL("DROP TABLE IF EXISTS " + SoundModelContract.TABLE);
onCreate(db);
}
/**
* TODO(sansid): Change to addOrUpdate to handle changes here.
*/
public void addKeyphraseSoundModel(KeyphraseSoundModel soundModel) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
// Generate a random ID for the model.
values.put(SoundModelContract.KEY_ID, soundModel.uuid.toString());
values.put(SoundModelContract.KEY_DATA, soundModel.data);
values.put(SoundModelContract.KEY_TYPE, SoundTrigger.SoundModel.TYPE_KEYPHRASE);
if (db.insert(SoundModelContract.TABLE, null, values) != -1) {
for (Keyphrase keyphrase : soundModel.keyphrases) {
addKeyphrase(soundModel.uuid, keyphrase);
}
} else {
Slog.w(TAG, "Failed to persist sound model to database");
}
}
/**
* TODO(sansid): Change to addOrUpdate to handle changes here.
*/
private void addKeyphrase(UUID modelId, SoundTrigger.Keyphrase keyphrase) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KeyphraseContract.KEY_ID, keyphrase.id);
values.put(KeyphraseContract.KEY_RECOGNITION_MODES, keyphrase.recognitionModes);
values.put(KeyphraseContract.KEY_SOUND_MODEL_ID, keyphrase.id);
values.put(KeyphraseContract.KEY_HINT_TEXT, keyphrase.text);
values.put(KeyphraseContract.KEY_LOCALE, keyphrase.locale);
if (db.insert(KeyphraseContract.TABLE, null, values) == -1) {
Slog.w(TAG, "Failed to persist keyphrase to database");
}
}
/**
* Lists all the keyphrase sound models currently registered with the system.
*/
public List<KeyphraseSoundModel> getKephraseSoundModels() {
List<KeyphraseSoundModel> models = new ArrayList<>();
String selectQuery = "SELECT * FROM " + SoundModelContract.TABLE;
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (c.moveToFirst()) {
do {
int type = c.getInt(c.getColumnIndex(SoundModelContract.KEY_TYPE));
if (type != SoundTrigger.SoundModel.TYPE_KEYPHRASE) {
// Ignore non-keyphrase sound models.
continue;
}
String id = c.getString(c.getColumnIndex(SoundModelContract.KEY_ID));
byte[] data = c.getBlob(c.getColumnIndex(SoundModelContract.KEY_DATA));
// Get all the keyphrases for this this sound model.
models.add(new KeyphraseSoundModel(
UUID.fromString(id), data, getKeyphrasesForSoundModel(id)));
} while (c.moveToNext());
}
return models;
}
private Keyphrase[] getKeyphrasesForSoundModel(String modelId) {
List<Keyphrase> keyphrases = new ArrayList<>();
String selectQuery = "SELECT * FROM " + KeyphraseContract.TABLE
+ " WHERE " + KeyphraseContract.KEY_SOUND_MODEL_ID + " = '" + modelId + "'";
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (c.moveToFirst()) {
do {
int id = c.getInt(c.getColumnIndex(KeyphraseContract.KEY_ID));
int modes = c.getInt(c.getColumnIndex(KeyphraseContract.KEY_RECOGNITION_MODES));
int numUsers = c.getInt(c.getColumnIndex(KeyphraseContract.KEY_NUM_USERS));
String locale = c.getString(c.getColumnIndex(KeyphraseContract.KEY_LOCALE));
String hintText = c.getString(c.getColumnIndex(KeyphraseContract.KEY_HINT_TEXT));
keyphrases.add(new Keyphrase(id, modes, locale, hintText, numUsers));
} while (c.moveToNext());
}
Keyphrase[] keyphraseArr = new Keyphrase[keyphrases.size()];
keyphrases.toArray(keyphraseArr);
return keyphraseArr;
}
}