android_hardware_SoundTrigger.cpp revision 013f66b92db609fceeff9c8171daca13d057cc95
160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent/*
260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent**
360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** Copyright 2014, The Android Open Source Project
460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent**
560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** Licensed under the Apache License, Version 2.0 (the "License");
660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** you may not use this file except in compliance with the License.
760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** You may obtain a copy of the License at
860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent**
960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent**     http://www.apache.org/licenses/LICENSE-2.0
1060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent**
1160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** Unless required by applicable law or agreed to in writing, software
1260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** distributed under the License is distributed on an "AS IS" BASIS,
1360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** See the License for the specific language governing permissions and
1560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** limitations under the License.
1660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent*/
1760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
1860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent//#define LOG_NDEBUG 0
1960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#define LOG_TAG "SoundTrigger-JNI"
2060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <utils/Log.h>
2160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
2260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include "jni.h"
2360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include "JNIHelp.h"
2460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include "android_runtime/AndroidRuntime.h"
2560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <system/sound_trigger.h>
2660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <soundtrigger/SoundTriggerCallback.h>
2760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <soundtrigger/SoundTrigger.h>
2860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <utils/RefBase.h>
2960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <utils/Vector.h>
3060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <binder/IMemory.h>
3160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <binder/MemoryDealer.h>
3260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
3360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentusing namespace android;
3460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
3560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gArrayListClass;
3660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct {
3760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jmethodID    add;
3860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} gArrayListMethods;
3960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
40d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gUUIDClass;
41d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic struct {
42d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jmethodID    toString;
43d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha} gUUIDMethods;
44d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
4560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kSoundTriggerClassPathName = "android/hardware/soundtrigger/SoundTrigger";
4660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gSoundTriggerClass;
4760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
4860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kModuleClassPathName = "android/hardware/soundtrigger/SoundTriggerModule";
4960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gModuleClass;
5060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct {
5160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jfieldID    mNativeContext;
5260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jfieldID    mId;
5360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} gModuleFields;
5460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jmethodID   gPostEventFromNative;
5560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
5660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kModulePropertiesClassPathName =
5760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                     "android/hardware/soundtrigger/SoundTrigger$ModuleProperties";
5860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gModulePropertiesClass;
5960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jmethodID   gModulePropertiesCstor;
6060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
6160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kSoundModelClassPathName =
6260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                     "android/hardware/soundtrigger/SoundTrigger$SoundModel";
6360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gSoundModelClass;
6460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct {
65d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jfieldID    uuid;
6660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jfieldID    data;
6760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} gSoundModelFields;
6860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
69d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic const char* const kKeyphraseClassPathName =
70d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                                     "android/hardware/soundtrigger/SoundTrigger$Keyphrase";
71d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gKeyphraseClass;
7260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct {
73d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jfieldID id;
7460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jfieldID recognitionModes;
7560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jfieldID locale;
7660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jfieldID text;
77013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jfieldID users;
78d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha} gKeyphraseFields;
7960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
80d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic const char* const kKeyphraseSoundModelClassPathName =
81d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                                 "android/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel";
82d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gKeyphraseSoundModelClass;
8360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct {
84d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jfieldID    keyphrases;
85d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha} gKeyphraseSoundModelFields;
8660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
87013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic const char* const kRecognitionConfigClassPathName =
88013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                     "android/hardware/soundtrigger/SoundTrigger$RecognitionConfig";
89013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic jclass gRecognitionConfigClass;
90013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic struct {
91013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jfieldID captureRequested;
92013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jfieldID keyphrases;
93013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jfieldID data;
94013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent} gRecognitionConfigFields;
9560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
9660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kRecognitionEventClassPathName =
9760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                     "android/hardware/soundtrigger/SoundTrigger$RecognitionEvent";
9860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gRecognitionEventClass;
9960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jmethodID   gRecognitionEventCstor;
10060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
101d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic const char* const kKeyphraseRecognitionEventClassPathName =
102d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                             "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent";
103d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gKeyphraseRecognitionEventClass;
104d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jmethodID   gKeyphraseRecognitionEventCstor;
10560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
106d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic const char* const kKeyphraseRecognitionExtraClassPathName =
107d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                             "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra";
108d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gKeyphraseRecognitionExtraClass;
109d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jmethodID   gKeyphraseRecognitionExtraCstor;
110013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic struct {
111013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jfieldID id;
112013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jfieldID recognitionModes;
113013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jfieldID confidenceLevels;
114013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent} gKeyphraseRecognitionExtraFields;
115013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
116013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic const char* const kConfidenceLevelClassPathName =
117013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                             "android/hardware/soundtrigger/SoundTrigger$ConfidenceLevel";
118013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic jclass gConfidenceLevelClass;
119013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic jmethodID   gConfidenceLevelCstor;
120013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic struct {
121013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jfieldID userId;
122013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jfieldID confidenceLevel;
123013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent} gConfidenceLevelFields;
12460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
12560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic Mutex gLock;
12660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
12760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentenum {
12860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SOUNDTRIGGER_STATUS_OK = 0,
12960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SOUNDTRIGGER_STATUS_ERROR = INT_MIN,
13060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SOUNDTRIGGER_PERMISSION_DENIED = -1,
13160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SOUNDTRIGGER_STATUS_NO_INIT = -19,
13260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SOUNDTRIGGER_STATUS_BAD_VALUE = -22,
13360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SOUNDTRIGGER_STATUS_DEAD_OBJECT = -32,
13460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SOUNDTRIGGER_INVALID_OPERATION = -38,
13560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent};
13660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
13760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentenum  {
13860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SOUNDTRIGGER_EVENT_RECOGNITION = 1,
13960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SOUNDTRIGGER_EVENT_SERVICE_DIED = 2,
14060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent};
14160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
14260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent// ----------------------------------------------------------------------------
14360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent// ref-counted object for callbacks
14460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentclass JNISoundTriggerCallback: public SoundTriggerCallback
14560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
14660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentpublic:
14760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
14860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ~JNISoundTriggerCallback();
14960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
15060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    virtual void onRecognitionEvent(struct sound_trigger_recognition_event *event);
15160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    virtual void onServiceDied();
15260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
15360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentprivate:
15460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jclass      mClass;     // Reference to SoundTrigger class
15560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jobject     mObject;    // Weak ref to SoundTrigger Java object to call on
15660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent};
15760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
15860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric LaurentJNISoundTriggerCallback::JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
15960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
16060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
16160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    // Hold onto the SoundTriggerModule class for use in calling the static method
16260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    // that posts events to the application thread.
16360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jclass clazz = env->GetObjectClass(thiz);
16460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (clazz == NULL) {
16560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        ALOGE("Can't find class %s", kModuleClassPathName);
16660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return;
16760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
16860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    mClass = (jclass)env->NewGlobalRef(clazz);
16960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
17060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    // We use a weak reference so the SoundTriggerModule object can be garbage collected.
17160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    // The reference is only used as a proxy for callbacks.
17260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    mObject  = env->NewGlobalRef(weak_thiz);
17360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
17460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
17560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric LaurentJNISoundTriggerCallback::~JNISoundTriggerCallback()
17660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
17760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    // remove global references
17860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    JNIEnv *env = AndroidRuntime::getJNIEnv();
17960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    env->DeleteGlobalRef(mObject);
18060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    env->DeleteGlobalRef(mClass);
18160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
18260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
18360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentvoid JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognition_event *event)
18460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
18560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    JNIEnv *env = AndroidRuntime::getJNIEnv();
18660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
18760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jobject jEvent;
18860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
18960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jbyteArray jData = NULL;
19060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (event->data_size) {
19160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        jData = env->NewByteArray(event->data_size);
19260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        jbyte *nData = env->GetByteArrayElements(jData, NULL);
19360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        memcpy(nData, (char *)event + event->data_offset, event->data_size);
19460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        env->ReleaseByteArrayElements(jData, nData, 0);
19560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
19660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
19760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (event->type == SOUND_MODEL_TYPE_KEYPHRASE) {
19860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        struct sound_trigger_phrase_recognition_event *phraseEvent =
19960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                (struct sound_trigger_phrase_recognition_event *)event;
20060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
20160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        jobjectArray jExtras = env->NewObjectArray(phraseEvent->num_phrases,
202d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                                                  gKeyphraseRecognitionExtraClass, NULL);
20360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        if (jExtras == NULL) {
20460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            return;
20560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        }
20660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
20760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        for (size_t i = 0; i < phraseEvent->num_phrases; i++) {
208013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            jobjectArray jConfidenceLevels = env->NewObjectArray(
209013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                        phraseEvent->phrase_extras[i].num_levels,
210013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                        gConfidenceLevelClass, NULL);
211013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
21260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            if (jConfidenceLevels == NULL) {
21360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                return;
21460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            }
215013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            for (size_t j = 0; j < phraseEvent->phrase_extras[i].num_levels; j++) {
216013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                jobject jConfidenceLevel = env->NewObject(gConfidenceLevelClass,
217013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                  gConfidenceLevelCstor,
218013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                  phraseEvent->phrase_extras[i].levels[j].user_id,
219013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                  phraseEvent->phrase_extras[i].levels[j].level);
220013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                env->SetObjectArrayElement(jConfidenceLevels, j, jConfidenceLevel);
221013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                env->DeleteLocalRef(jConfidenceLevel);
222013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            }
223013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
224d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha            jobject jNewExtra = env->NewObject(gKeyphraseRecognitionExtraClass,
225d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                                               gKeyphraseRecognitionExtraCstor,
226013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                               phraseEvent->phrase_extras[i].id,
227013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                               phraseEvent->phrase_extras[i].recognition_modes,
228013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                               jConfidenceLevels);
22960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
23060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            if (jNewExtra == NULL) {
23160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                return;
23260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            }
23360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            env->SetObjectArrayElement(jExtras, i, jNewExtra);
234013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            env->DeleteLocalRef(jNewExtra);
235013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            env->DeleteLocalRef(jConfidenceLevels);
23660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        }
237d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        jEvent = env->NewObject(gKeyphraseRecognitionEventClass, gKeyphraseRecognitionEventCstor,
23860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                event->status, event->model, event->capture_available,
239013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                               event->capture_session, event->capture_delay_ms,
240013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                               event->capture_preamble_ms, jData,
24160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                               phraseEvent->key_phrase_in_capture, jExtras);
24260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    } else {
24360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        jEvent = env->NewObject(gRecognitionEventClass, gRecognitionEventCstor,
24460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                event->status, event->model, event->capture_available,
245013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                event->capture_session, event->capture_delay_ms,
246013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                event->capture_preamble_ms, jData);
24760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
24860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
24960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
25060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
25160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                              SOUNDTRIGGER_EVENT_RECOGNITION, 0, 0, jEvent);
25260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (env->ExceptionCheck()) {
25360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        ALOGW("An exception occurred while notifying an event.");
25460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        env->ExceptionClear();
25560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
25660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
25760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
25860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentvoid JNISoundTriggerCallback::onServiceDied()
25960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
26060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    JNIEnv *env = AndroidRuntime::getJNIEnv();
26160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
26260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
26360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                              SOUNDTRIGGER_EVENT_SERVICE_DIED, 0, 0, NULL);
26460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (env->ExceptionCheck()) {
26560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        ALOGW("An exception occurred while notifying an event.");
26660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        env->ExceptionClear();
26760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
26860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
26960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
27060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent// ----------------------------------------------------------------------------
27160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
27260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic sp<SoundTrigger> getSoundTrigger(JNIEnv* env, jobject thiz)
27360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
27460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    Mutex::Autolock l(gLock);
27560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    SoundTrigger* const st = (SoundTrigger*)env->GetLongField(thiz,
27660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                                         gModuleFields.mNativeContext);
27760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    return sp<SoundTrigger>(st);
27860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
27960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
28060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic sp<SoundTrigger> setSoundTrigger(JNIEnv* env, jobject thiz, const sp<SoundTrigger>& module)
28160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
28260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    Mutex::Autolock l(gLock);
28360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<SoundTrigger> old = (SoundTrigger*)env->GetLongField(thiz,
28460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                                         gModuleFields.mNativeContext);
28560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (module.get()) {
28660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        module->incStrong((void*)setSoundTrigger);
28760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
28860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (old != 0) {
28960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        old->decStrong((void*)setSoundTrigger);
29060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
29160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    env->SetLongField(thiz, gModuleFields.mNativeContext, (jlong)module.get());
29260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    return old;
29360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
29460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
29560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
29660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint
29760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_listModules(JNIEnv *env, jobject clazz,
29860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                          jobject jModules)
29960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
30060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("listModules");
30160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
30260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (jModules == NULL) {
30360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        ALOGE("listModules NULL AudioPatch ArrayList");
30460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return SOUNDTRIGGER_STATUS_BAD_VALUE;
30560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
30660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (!env->IsInstanceOf(jModules, gArrayListClass)) {
30760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        ALOGE("listModules not an arraylist");
30860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return SOUNDTRIGGER_STATUS_BAD_VALUE;
30960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
31060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
31160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    unsigned int numModules = 0;
31260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    struct sound_trigger_module_descriptor *nModules = NULL;
31360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
31460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    status_t status = SoundTrigger::listModules(nModules, &numModules);
31560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (status != NO_ERROR || numModules == 0) {
31660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return (jint)status;
31760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
31860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
31960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    nModules = (struct sound_trigger_module_descriptor *)
32060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                            calloc(numModules, sizeof(struct sound_trigger_module_descriptor));
32160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
32260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    status = SoundTrigger::listModules(nModules, &numModules);
32360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("listModules SoundTrigger::listModules status %d numModules %d", status, numModules);
32460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
32560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (status != NO_ERROR) {
32660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        numModules = 0;
32760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
32860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
32960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    for (size_t i = 0; i < numModules; i++) {
33060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        char str[SOUND_TRIGGER_MAX_STRING_LEN];
33160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
33260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        jstring implementor = env->NewStringUTF(nModules[i].properties.implementor);
33360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        jstring description = env->NewStringUTF(nModules[i].properties.description);
33460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        SoundTrigger::guidToString(&nModules[i].properties.uuid,
33560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                   str,
33660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                   SOUND_TRIGGER_MAX_STRING_LEN);
33760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        jstring uuid = env->NewStringUTF(str);
33860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
33960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        ALOGV("listModules module %d id %d description %s maxSoundModels %d",
34060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent              i, nModules[i].handle, nModules[i].properties.description,
34160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent              nModules[i].properties.max_sound_models);
34260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
34360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        jobject newModuleDesc = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
34460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].handle,
34560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               implementor, description, uuid,
34660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].properties.version,
34760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].properties.max_sound_models,
34860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].properties.max_key_phrases,
34960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].properties.max_users,
35060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].properties.recognition_modes,
35160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].properties.capture_transition,
35260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].properties.max_buffer_ms,
35360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].properties.concurrent_capture,
35460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               nModules[i].properties.power_consumption_mw);
35560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
35660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        env->DeleteLocalRef(implementor);
35760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        env->DeleteLocalRef(description);
35860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        env->DeleteLocalRef(uuid);
35960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        if (newModuleDesc == NULL) {
36060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            status = SOUNDTRIGGER_STATUS_ERROR;
36160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            goto exit;
36260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        }
36360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        env->CallBooleanMethod(jModules, gArrayListMethods.add, newModuleDesc);
36460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
36560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
36660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentexit:
36760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    free(nModules);
36860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    return (jint) status;
36960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
37060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
37160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic void
37260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_setup(JNIEnv *env, jobject thiz, jobject weak_this)
37360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
37460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("setup");
37560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
37660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<JNISoundTriggerCallback> callback = new JNISoundTriggerCallback(env, thiz, weak_this);
37760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
37860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sound_trigger_module_handle_t handle =
37960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            (sound_trigger_module_handle_t)env->GetIntField(thiz, gModuleFields.mId);
38060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
38160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<SoundTrigger> module = SoundTrigger::attach(handle, callback);
38260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (module == 0) {
38360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return;
38460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
38560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
38660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    setSoundTrigger(env, thiz, module);
38760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
38860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
38960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic void
39060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_detach(JNIEnv *env, jobject thiz)
39160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
39260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("detach");
39360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<SoundTrigger> module = setSoundTrigger(env, thiz, 0);
39460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("detach module %p", module.get());
39560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (module != 0) {
39660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        ALOGV("detach module->detach()");
39760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        module->detach();
39860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
39960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
40060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
40160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic void
40260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_finalize(JNIEnv *env, jobject thiz)
40360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
40460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("finalize");
40560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
40660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (module != 0) {
40760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        ALOGW("SoundTrigger finalized without being detached");
40860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
40960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    android_hardware_SoundTrigger_detach(env, thiz);
41060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
41160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
41260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint
41360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
41460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                             jobject jSoundModel, jintArray jHandle)
41560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
41660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jint status = SOUNDTRIGGER_STATUS_OK;
417013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jbyte *nData = NULL;
41860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    struct sound_trigger_sound_model *nSoundModel;
41960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jbyteArray jData;
42060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<MemoryDealer> memoryDealer;
42160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<IMemory> memory;
42260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    size_t size;
42360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sound_model_handle_t handle;
424d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jobject jUuid;
425d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jstring jUuidString;
426d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    const char *nUuidString;
42760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
42860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("loadSoundModel");
42960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
43060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (module == NULL) {
43160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return SOUNDTRIGGER_STATUS_ERROR;
43260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
43360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (jHandle == NULL) {
43460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return SOUNDTRIGGER_STATUS_BAD_VALUE;
43560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
43660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jsize jHandleLen = env->GetArrayLength(jHandle);
43760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (jHandleLen == 0) {
43860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return SOUNDTRIGGER_STATUS_BAD_VALUE;
43960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
44060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jint *nHandle = env->GetIntArrayElements(jHandle, NULL);
44160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (nHandle == NULL) {
44260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return SOUNDTRIGGER_STATUS_ERROR;
44360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
44460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (!env->IsInstanceOf(jSoundModel, gSoundModelClass)) {
44560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        status = SOUNDTRIGGER_STATUS_BAD_VALUE;
44660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        goto exit;
44760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
44860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    size_t offset;
44960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sound_trigger_sound_model_type_t type;
450d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    if (env->IsInstanceOf(jSoundModel, gKeyphraseSoundModelClass)) {
45160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        offset = sizeof(struct sound_trigger_phrase_sound_model);
45260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        type = SOUND_MODEL_TYPE_KEYPHRASE;
45360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    } else {
45460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        offset = sizeof(struct sound_trigger_sound_model);
45560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        type = SOUND_MODEL_TYPE_UNKNOWN;
45660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
457d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
458d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.uuid);
459d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
460d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    nUuidString = env->GetStringUTFChars(jUuidString, NULL);
461d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    sound_trigger_uuid_t nUuid;
462d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    SoundTrigger::stringToGuid(nUuidString, &nUuid);
463d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    env->ReleaseStringUTFChars(jUuidString, nUuidString);
464d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    env->DeleteLocalRef(jUuidString);
465d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
46660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jData = (jbyteArray)env->GetObjectField(jSoundModel, gSoundModelFields.data);
46760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (jData == NULL) {
46860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        status = SOUNDTRIGGER_STATUS_BAD_VALUE;
46960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        goto exit;
47060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
47160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    size = env->GetArrayLength(jData);
47260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
473013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    nData = env->GetByteArrayElements(jData, NULL);
47460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (jData == NULL) {
47560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        status = SOUNDTRIGGER_STATUS_ERROR;
47660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        goto exit;
47760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
47860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
47960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    memoryDealer = new MemoryDealer(offset + size, "SoundTrigge-JNI::LoadModel");
48060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (memoryDealer == 0) {
48160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        status = SOUNDTRIGGER_STATUS_ERROR;
48260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        goto exit;
48360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
48460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    memory = memoryDealer->allocate(offset + size);
48560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (memory == 0 || memory->pointer() == NULL) {
48660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        status = SOUNDTRIGGER_STATUS_ERROR;
48760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        goto exit;
48860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
48960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
49060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    nSoundModel = (struct sound_trigger_sound_model *)memory->pointer();
49160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
49260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    nSoundModel->type = type;
493d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    nSoundModel->uuid = nUuid;
49460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    nSoundModel->data_size = size;
49560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    nSoundModel->data_offset = offset;
49660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    memcpy((char *)nSoundModel + offset, nData, size);
49760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (type == SOUND_MODEL_TYPE_KEYPHRASE) {
49860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        struct sound_trigger_phrase_sound_model *phraseModel =
49960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                (struct sound_trigger_phrase_sound_model *)nSoundModel;
50060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
50160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        jobjectArray jPhrases =
502d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha            (jobjectArray)env->GetObjectField(jSoundModel, gKeyphraseSoundModelFields.keyphrases);
50360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        if (jPhrases == NULL) {
50460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            status = SOUNDTRIGGER_STATUS_BAD_VALUE;
50560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            goto exit;
50660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        }
50760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
50860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        size_t numPhrases = env->GetArrayLength(jPhrases);
50960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        phraseModel->num_phrases = numPhrases;
51060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        ALOGV("loadSoundModel numPhrases %d", numPhrases);
51160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        for (size_t i = 0; i < numPhrases; i++) {
51260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
513d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha            phraseModel->phrases[i].id =
514d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                                    env->GetIntField(jPhrase,gKeyphraseFields.id);
51560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            phraseModel->phrases[i].recognition_mode =
516d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                                    env->GetIntField(jPhrase,gKeyphraseFields.recognitionModes);
517013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
518013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            jintArray jUsers = (jintArray)env->GetObjectField(jPhrase, gKeyphraseFields.users);
519013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            phraseModel->phrases[i].num_users = env->GetArrayLength(jUsers);
520013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            jint *nUsers = env->GetIntArrayElements(jUsers, NULL);
521013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            memcpy(phraseModel->phrases[i].users,
522013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                   nUsers,
523013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                   phraseModel->phrases[i].num_users * sizeof(int));
524013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            env->ReleaseIntArrayElements(jUsers, nUsers, 0);
525013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            env->DeleteLocalRef(jUsers);
526013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
527d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha            jstring jLocale = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.locale);
52860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            const char *nLocale = env->GetStringUTFChars(jLocale, NULL);
52960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            strncpy(phraseModel->phrases[i].locale,
53060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                    nLocale,
53160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                    SOUND_TRIGGER_MAX_LOCALE_LEN);
532d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha            jstring jText = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.text);
53360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            const char *nText = env->GetStringUTFChars(jText, NULL);
53460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            strncpy(phraseModel->phrases[i].text,
53560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                    nText,
53660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                    SOUND_TRIGGER_MAX_STRING_LEN);
53760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
53860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            env->ReleaseStringUTFChars(jLocale, nLocale);
53960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            env->DeleteLocalRef(jLocale);
54060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            env->ReleaseStringUTFChars(jText, nText);
54160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            env->DeleteLocalRef(jText);
54260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            ALOGV("loadSoundModel phrases %d text %s locale %s",
54360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                  i, phraseModel->phrases[i].text, phraseModel->phrases[i].locale);
544013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            env->DeleteLocalRef(jPhrase);
54560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        }
54660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        env->DeleteLocalRef(jPhrases);
54760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
54860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    status = module->loadSoundModel(memory, &handle);
54960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("loadSoundModel status %d handle %d", status, handle);
55060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
55160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentexit:
55260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (nHandle != NULL) {
55360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        nHandle[0] = (jint)handle;
55460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        env->ReleaseIntArrayElements(jHandle, nHandle, NULL);
55560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
55660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (nData != NULL) {
557013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        env->ReleaseByteArrayElements(jData, nData, NULL);
55860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
55960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    return status;
56060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
56160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
56260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint
56360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_unloadSoundModel(JNIEnv *env, jobject thiz,
56460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               jint jHandle)
56560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
56660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jint status = SOUNDTRIGGER_STATUS_OK;
56760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("unloadSoundModel");
56860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
56960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (module == NULL) {
57060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return SOUNDTRIGGER_STATUS_ERROR;
57160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
57260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    status = module->unloadSoundModel((sound_model_handle_t)jHandle);
57360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
57460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    return status;
57560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
57660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
57760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint
57860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_startRecognition(JNIEnv *env, jobject thiz,
579013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                               jint jHandle, jobject jConfig)
58060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
58160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jint status = SOUNDTRIGGER_STATUS_OK;
58260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("startRecognition");
58360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
58460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (module == NULL) {
58560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return SOUNDTRIGGER_STATUS_ERROR;
58660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
587013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
588013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    if (!env->IsInstanceOf(jConfig, gRecognitionConfigClass)) {
589013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        return SOUNDTRIGGER_STATUS_BAD_VALUE;
590013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    }
591013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
592013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jbyteArray jData = (jbyteArray)env->GetObjectField(jConfig, gRecognitionConfigFields.data);
59360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jsize dataSize = 0;
594013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jbyte *nData = NULL;
59560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (jData != NULL) {
59660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        dataSize = env->GetArrayLength(jData);
59760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        if (dataSize == 0) {
59860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            return SOUNDTRIGGER_STATUS_BAD_VALUE;
59960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        }
600013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        nData = env->GetByteArrayElements(jData, NULL);
60160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        if (nData == NULL) {
60260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent            return SOUNDTRIGGER_STATUS_ERROR;
60360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        }
604013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    }
605013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
606013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    size_t totalSize = sizeof(struct sound_trigger_recognition_config) + dataSize;
607013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    sp<MemoryDealer> memoryDealer =
608013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            new MemoryDealer(totalSize, "SoundTrigge-JNI::StartRecognition");
609013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    if (memoryDealer == 0) {
610013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        return SOUNDTRIGGER_STATUS_ERROR;
611013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    }
612013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    sp<IMemory> memory = memoryDealer->allocate(totalSize);
613013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    if (memory == 0 || memory->pointer() == NULL) {
614013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        return SOUNDTRIGGER_STATUS_ERROR;
615013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    }
616013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    if (dataSize != 0) {
617013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        memcpy((char *)memory->pointer() + sizeof(struct sound_trigger_recognition_config),
618013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                nData,
619013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                dataSize);
620013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        env->ReleaseByteArrayElements(jData, nData, 0);
621013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    }
622013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    env->DeleteLocalRef(jData);
623013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    struct sound_trigger_recognition_config *config =
624013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                    (struct sound_trigger_recognition_config *)memory->pointer();
625013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    config->data_size = dataSize;
626013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    config->data_offset = sizeof(struct sound_trigger_recognition_config);
627013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    config->capture_requested = env->GetIntField(jConfig,
628013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                 gRecognitionConfigFields.captureRequested);
629013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
630013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    config->num_phrases = 0;
631013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jobjectArray jPhrases =
632013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        (jobjectArray)env->GetObjectField(jConfig, gRecognitionConfigFields.keyphrases);
633013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    if (jPhrases != NULL) {
634013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        config->num_phrases = env->GetArrayLength(jPhrases);
635013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    }
636013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    ALOGV("startRecognition num phrases %d", config->num_phrases);
637013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    for (size_t i = 0; i < config->num_phrases; i++) {
638013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
639013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        config->phrases[i].id = env->GetIntField(jPhrase,
640013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                gKeyphraseRecognitionExtraFields.id);
641013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        config->phrases[i].recognition_modes = env->GetIntField(jPhrase,
642013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                gKeyphraseRecognitionExtraFields.recognitionModes);
643013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        config->phrases[i].num_levels = 0;
644013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        jobjectArray jConfidenceLevels = (jobjectArray)env->GetObjectField(jPhrase,
645013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                gKeyphraseRecognitionExtraFields.confidenceLevels);
646013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        if (jConfidenceLevels != NULL) {
647013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            config->phrases[i].num_levels = env->GetArrayLength(jConfidenceLevels);
64860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        }
649013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        ALOGV("startRecognition phrase %d num_levels %d", i, config->phrases[i].num_levels);
650013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        for (size_t j = 0; j < config->phrases[i].num_levels; j++) {
651013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            jobject jConfidenceLevel = env->GetObjectArrayElement(jConfidenceLevels, j);
652013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            config->phrases[i].levels[j].user_id = env->GetIntField(jConfidenceLevel,
653013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                                    gConfidenceLevelFields.userId);
654013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            config->phrases[i].levels[j].level = env->GetIntField(jConfidenceLevel,
655013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                          gConfidenceLevelFields.confidenceLevel);
656013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent            env->DeleteLocalRef(jConfidenceLevel);
65760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        }
658013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        ALOGV("startRecognition phrases %d", i);
659013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        env->DeleteLocalRef(jConfidenceLevels);
660013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        env->DeleteLocalRef(jPhrase);
66160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
662013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    env->DeleteLocalRef(jPhrases);
66360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
66460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    status = module->startRecognition(jHandle, memory);
66560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    return status;
66660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
66760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
66860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint
66960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_stopRecognition(JNIEnv *env, jobject thiz,
67060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                               jint jHandle)
67160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
67260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jint status = SOUNDTRIGGER_STATUS_OK;
67360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    ALOGV("stopRecognition");
67460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
67560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (module == NULL) {
67660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        return SOUNDTRIGGER_STATUS_ERROR;
67760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
67860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    status = module->stopRecognition(jHandle);
67960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    return status;
68060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
68160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
68260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic JNINativeMethod gMethods[] = {
68360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    {"listModules",
68460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        "(Ljava/util/ArrayList;)I",
68560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        (void *)android_hardware_SoundTrigger_listModules},
68660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent};
68760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
68860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
68960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic JNINativeMethod gModuleMethods[] = {
69060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    {"native_setup",
69160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        "(Ljava/lang/Object;)V",
69260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        (void *)android_hardware_SoundTrigger_setup},
69360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    {"native_finalize",
69460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        "()V",
69560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        (void *)android_hardware_SoundTrigger_finalize},
69660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    {"detach",
69760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        "()V",
69860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        (void *)android_hardware_SoundTrigger_detach},
69960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    {"loadSoundModel",
70060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        "(Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;[I)I",
70160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        (void *)android_hardware_SoundTrigger_loadSoundModel},
70260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    {"unloadSoundModel",
70360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        "(I)I",
70460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        (void *)android_hardware_SoundTrigger_unloadSoundModel},
70560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    {"startRecognition",
706013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent        "(ILandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;)I",
70760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        (void *)android_hardware_SoundTrigger_startRecognition},
70860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    {"stopRecognition",
70960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        "(I)I",
71060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        (void *)android_hardware_SoundTrigger_stopRecognition},
71160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent};
71260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
71360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentint register_android_hardware_SoundTrigger(JNIEnv *env)
71460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{
71560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jclass arrayListClass = env->FindClass("java/util/ArrayList");
71660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gArrayListClass = (jclass) env->NewGlobalRef(arrayListClass);
71760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gArrayListMethods.add = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
71860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
719d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jclass uuidClass = env->FindClass("java/util/UUID");
720d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gUUIDClass = (jclass) env->NewGlobalRef(uuidClass);
721d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gUUIDMethods.toString = env->GetMethodID(uuidClass, "toString", "()Ljava/lang/String;");
722d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
72360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jclass lClass = env->FindClass(kSoundTriggerClassPathName);
72460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gSoundTriggerClass = (jclass) env->NewGlobalRef(lClass);
72560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
72660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jclass moduleClass = env->FindClass(kModuleClassPathName);
72760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gModuleClass = (jclass) env->NewGlobalRef(moduleClass);
72860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gPostEventFromNative = env->GetStaticMethodID(moduleClass, "postEventFromNative",
72960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                                            "(Ljava/lang/Object;IIILjava/lang/Object;)V");
73060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gModuleFields.mNativeContext = env->GetFieldID(moduleClass, "mNativeContext", "J");
73160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gModuleFields.mId = env->GetFieldID(moduleClass, "mId", "I");
73260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
73360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
73460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jclass modulePropertiesClass = env->FindClass(kModulePropertiesClassPathName);
73560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gModulePropertiesClass = (jclass) env->NewGlobalRef(modulePropertiesClass);
73660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gModulePropertiesCstor = env->GetMethodID(modulePropertiesClass, "<init>",
73760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                              "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZI)V");
73860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
73960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jclass soundModelClass = env->FindClass(kSoundModelClassPathName);
74060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gSoundModelClass = (jclass) env->NewGlobalRef(soundModelClass);
741d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gSoundModelFields.uuid = env->GetFieldID(soundModelClass, "uuid", "Ljava/util/UUID;");
74260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gSoundModelFields.data = env->GetFieldID(soundModelClass, "data", "[B");
74360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
744d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jclass keyphraseClass = env->FindClass(kKeyphraseClassPathName);
745d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseClass = (jclass) env->NewGlobalRef(keyphraseClass);
746d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseFields.id = env->GetFieldID(keyphraseClass, "id", "I");
747d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseFields.recognitionModes = env->GetFieldID(keyphraseClass, "recognitionModes", "I");
748d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseFields.locale = env->GetFieldID(keyphraseClass, "locale", "Ljava/lang/String;");
749d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseFields.text = env->GetFieldID(keyphraseClass, "text", "Ljava/lang/String;");
750013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gKeyphraseFields.users = env->GetFieldID(keyphraseClass, "users", "[I");
75160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
752d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jclass keyphraseSoundModelClass = env->FindClass(kKeyphraseSoundModelClassPathName);
753d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseSoundModelClass = (jclass) env->NewGlobalRef(keyphraseSoundModelClass);
754d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseSoundModelFields.keyphrases = env->GetFieldID(keyphraseSoundModelClass,
755d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                                         "keyphrases",
756d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha                                         "[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;");
75760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
75860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
75960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    jclass recognitionEventClass = env->FindClass(kRecognitionEventClassPathName);
76060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gRecognitionEventClass = (jclass) env->NewGlobalRef(recognitionEventClass);
76160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    gRecognitionEventCstor = env->GetMethodID(recognitionEventClass, "<init>",
762013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                              "(IIZIII[B)V");
76360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
764d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jclass keyphraseRecognitionEventClass = env->FindClass(kKeyphraseRecognitionEventClassPathName);
765d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseRecognitionEventClass = (jclass) env->NewGlobalRef(keyphraseRecognitionEventClass);
766d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseRecognitionEventCstor = env->GetMethodID(keyphraseRecognitionEventClass, "<init>",
767013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent              "(IIZIII[BZ[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V");
768013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
76960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
770013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jclass keyRecognitionConfigClass = env->FindClass(kRecognitionConfigClassPathName);
771013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gRecognitionConfigClass = (jclass) env->NewGlobalRef(keyRecognitionConfigClass);
772013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gRecognitionConfigFields.captureRequested = env->GetFieldID(keyRecognitionConfigClass,
773013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                              "captureRequested",
774013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                              "Z");
775013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gRecognitionConfigFields.keyphrases = env->GetFieldID(keyRecognitionConfigClass,
776013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                        "keyphrases",
777013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                        "[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;");
778013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gRecognitionConfigFields.data = env->GetFieldID(keyRecognitionConfigClass,
779013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                              "data",
780013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                              "[B");
78160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
782d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    jclass keyphraseRecognitionExtraClass = env->FindClass(kKeyphraseRecognitionExtraClassPathName);
783d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseRecognitionExtraClass = (jclass) env->NewGlobalRef(keyphraseRecognitionExtraClass);
784d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    gKeyphraseRecognitionExtraCstor = env->GetMethodID(keyphraseRecognitionExtraClass, "<init>",
785013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                           "(II[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V");
786013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gKeyphraseRecognitionExtraFields.id = env->GetFieldID(gKeyphraseRecognitionExtraClass, "id", "I");
787013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gKeyphraseRecognitionExtraFields.recognitionModes = env->GetFieldID(gKeyphraseRecognitionExtraClass, "recognitionModes", "I");
788013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gKeyphraseRecognitionExtraFields.confidenceLevels = env->GetFieldID(gKeyphraseRecognitionExtraClass,
789013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                             "confidenceLevels",
790013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                             "[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;");
791013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
792013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    jclass confidenceLevelClass = env->FindClass(kConfidenceLevelClassPathName);
793013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gConfidenceLevelClass = (jclass) env->NewGlobalRef(confidenceLevelClass);
794013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gConfidenceLevelCstor = env->GetMethodID(confidenceLevelClass, "<init>", "(II)V");
795013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gConfidenceLevelFields.userId = env->GetFieldID(confidenceLevelClass, "userId", "I");
796013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent    gConfidenceLevelFields.confidenceLevel = env->GetFieldID(confidenceLevelClass,
797013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent                                                             "confidenceLevel", "I");
79860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
79960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    int status = AndroidRuntime::registerNativeMethods(env,
80060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                kSoundTriggerClassPathName, gMethods, NELEM(gMethods));
80160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
80260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    if (status == 0) {
80360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent        status = AndroidRuntime::registerNativeMethods(env,
80460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent                kModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));
80560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    }
80660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent
807013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent
80860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent    return status;
80960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}
810