Merge "Initial code for listing/storing sound models"
This commit is contained in:
committed by
Android (Google) Code Review
commit
a3bf3e5c84
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user