blob: 8436568e4f7fe1cbb0231d653f201b2c8c0e10b3 [file] [log] [blame]
Eric Laurent60b62bc2014-04-18 17:50:49 -07001/*
2**
3** Copyright 2014, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18//#define LOG_NDEBUG 0
19#define LOG_TAG "SoundTrigger-JNI"
20#include <utils/Log.h>
21
22#include "jni.h"
23#include "JNIHelp.h"
Andreas Gampeed6b9df2014-11-20 22:02:20 -080024#include "core_jni_helpers.h"
Eric Laurent60b62bc2014-04-18 17:50:49 -070025#include <system/sound_trigger.h>
26#include <soundtrigger/SoundTriggerCallback.h>
27#include <soundtrigger/SoundTrigger.h>
28#include <utils/RefBase.h>
29#include <utils/Vector.h>
30#include <binder/IMemory.h>
31#include <binder/MemoryDealer.h>
Eric Laurentd3b82232014-07-30 08:57:39 -070032#include "android_media_AudioFormat.h"
Eric Laurent60b62bc2014-04-18 17:50:49 -070033
34using namespace android;
35
36static jclass gArrayListClass;
37static struct {
38 jmethodID add;
39} gArrayListMethods;
40
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070041static jclass gUUIDClass;
42static struct {
43 jmethodID toString;
44} gUUIDMethods;
45
Eric Laurent60b62bc2014-04-18 17:50:49 -070046static const char* const kSoundTriggerClassPathName = "android/hardware/soundtrigger/SoundTrigger";
47static jclass gSoundTriggerClass;
48
49static const char* const kModuleClassPathName = "android/hardware/soundtrigger/SoundTriggerModule";
50static jclass gModuleClass;
51static struct {
52 jfieldID mNativeContext;
53 jfieldID mId;
54} gModuleFields;
55static jmethodID gPostEventFromNative;
56
57static const char* const kModulePropertiesClassPathName =
58 "android/hardware/soundtrigger/SoundTrigger$ModuleProperties";
59static jclass gModulePropertiesClass;
60static jmethodID gModulePropertiesCstor;
61
62static const char* const kSoundModelClassPathName =
63 "android/hardware/soundtrigger/SoundTrigger$SoundModel";
64static jclass gSoundModelClass;
65static struct {
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070066 jfieldID uuid;
Eric Laurentd3b82232014-07-30 08:57:39 -070067 jfieldID vendorUuid;
Eric Laurent60b62bc2014-04-18 17:50:49 -070068 jfieldID data;
69} gSoundModelFields;
70
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070071static const char* const kKeyphraseClassPathName =
72 "android/hardware/soundtrigger/SoundTrigger$Keyphrase";
73static jclass gKeyphraseClass;
Eric Laurent60b62bc2014-04-18 17:50:49 -070074static struct {
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070075 jfieldID id;
Eric Laurent60b62bc2014-04-18 17:50:49 -070076 jfieldID recognitionModes;
77 jfieldID locale;
78 jfieldID text;
Eric Laurent013f66b2014-07-06 16:35:00 -070079 jfieldID users;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070080} gKeyphraseFields;
Eric Laurent60b62bc2014-04-18 17:50:49 -070081
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070082static const char* const kKeyphraseSoundModelClassPathName =
83 "android/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel";
84static jclass gKeyphraseSoundModelClass;
Eric Laurent60b62bc2014-04-18 17:50:49 -070085static struct {
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070086 jfieldID keyphrases;
87} gKeyphraseSoundModelFields;
Eric Laurent60b62bc2014-04-18 17:50:49 -070088
Eric Laurent013f66b2014-07-06 16:35:00 -070089static const char* const kRecognitionConfigClassPathName =
90 "android/hardware/soundtrigger/SoundTrigger$RecognitionConfig";
91static jclass gRecognitionConfigClass;
92static struct {
93 jfieldID captureRequested;
94 jfieldID keyphrases;
95 jfieldID data;
96} gRecognitionConfigFields;
Eric Laurent60b62bc2014-04-18 17:50:49 -070097
98static const char* const kRecognitionEventClassPathName =
99 "android/hardware/soundtrigger/SoundTrigger$RecognitionEvent";
100static jclass gRecognitionEventClass;
101static jmethodID gRecognitionEventCstor;
102
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700103static const char* const kKeyphraseRecognitionEventClassPathName =
104 "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent";
105static jclass gKeyphraseRecognitionEventClass;
106static jmethodID gKeyphraseRecognitionEventCstor;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700107
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700108static const char* const kKeyphraseRecognitionExtraClassPathName =
109 "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra";
110static jclass gKeyphraseRecognitionExtraClass;
111static jmethodID gKeyphraseRecognitionExtraCstor;
Eric Laurent013f66b2014-07-06 16:35:00 -0700112static struct {
113 jfieldID id;
114 jfieldID recognitionModes;
Eric Laurentd3b82232014-07-30 08:57:39 -0700115 jfieldID coarseConfidenceLevel;
Eric Laurent013f66b2014-07-06 16:35:00 -0700116 jfieldID confidenceLevels;
117} gKeyphraseRecognitionExtraFields;
118
119static const char* const kConfidenceLevelClassPathName =
120 "android/hardware/soundtrigger/SoundTrigger$ConfidenceLevel";
121static jclass gConfidenceLevelClass;
122static jmethodID gConfidenceLevelCstor;
123static struct {
124 jfieldID userId;
125 jfieldID confidenceLevel;
126} gConfidenceLevelFields;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700127
Eric Laurentd3b82232014-07-30 08:57:39 -0700128static const char* const kAudioFormatClassPathName =
129 "android/media/AudioFormat";
130static jclass gAudioFormatClass;
131static jmethodID gAudioFormatCstor;
132
133static const char* const kSoundModelEventClassPathName =
134 "android/hardware/soundtrigger/SoundTrigger$SoundModelEvent";
135static jclass gSoundModelEventClass;
136static jmethodID gSoundModelEventCstor;
137
Eric Laurent60b62bc2014-04-18 17:50:49 -0700138static Mutex gLock;
139
140enum {
141 SOUNDTRIGGER_STATUS_OK = 0,
142 SOUNDTRIGGER_STATUS_ERROR = INT_MIN,
143 SOUNDTRIGGER_PERMISSION_DENIED = -1,
144 SOUNDTRIGGER_STATUS_NO_INIT = -19,
145 SOUNDTRIGGER_STATUS_BAD_VALUE = -22,
146 SOUNDTRIGGER_STATUS_DEAD_OBJECT = -32,
147 SOUNDTRIGGER_INVALID_OPERATION = -38,
148};
149
150enum {
151 SOUNDTRIGGER_EVENT_RECOGNITION = 1,
152 SOUNDTRIGGER_EVENT_SERVICE_DIED = 2,
Eric Laurentd3b82232014-07-30 08:57:39 -0700153 SOUNDTRIGGER_EVENT_SOUNDMODEL = 3,
154 SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE = 4,
Eric Laurent60b62bc2014-04-18 17:50:49 -0700155};
156
157// ----------------------------------------------------------------------------
158// ref-counted object for callbacks
159class JNISoundTriggerCallback: public SoundTriggerCallback
160{
161public:
162 JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
163 ~JNISoundTriggerCallback();
164
165 virtual void onRecognitionEvent(struct sound_trigger_recognition_event *event);
Eric Laurentd3b82232014-07-30 08:57:39 -0700166 virtual void onSoundModelEvent(struct sound_trigger_model_event *event);
167 virtual void onServiceStateChange(sound_trigger_service_state_t state);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700168 virtual void onServiceDied();
169
170private:
171 jclass mClass; // Reference to SoundTrigger class
172 jobject mObject; // Weak ref to SoundTrigger Java object to call on
173};
174
175JNISoundTriggerCallback::JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
176{
177
178 // Hold onto the SoundTriggerModule class for use in calling the static method
179 // that posts events to the application thread.
180 jclass clazz = env->GetObjectClass(thiz);
181 if (clazz == NULL) {
182 ALOGE("Can't find class %s", kModuleClassPathName);
183 return;
184 }
185 mClass = (jclass)env->NewGlobalRef(clazz);
186
187 // We use a weak reference so the SoundTriggerModule object can be garbage collected.
188 // The reference is only used as a proxy for callbacks.
189 mObject = env->NewGlobalRef(weak_thiz);
190}
191
192JNISoundTriggerCallback::~JNISoundTriggerCallback()
193{
194 // remove global references
195 JNIEnv *env = AndroidRuntime::getJNIEnv();
196 env->DeleteGlobalRef(mObject);
197 env->DeleteGlobalRef(mClass);
198}
199
200void JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognition_event *event)
201{
202 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurentd3b82232014-07-30 08:57:39 -0700203 jobject jEvent = NULL;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700204 jbyteArray jData = NULL;
Eric Laurentd3b82232014-07-30 08:57:39 -0700205
Eric Laurent60b62bc2014-04-18 17:50:49 -0700206 if (event->data_size) {
207 jData = env->NewByteArray(event->data_size);
208 jbyte *nData = env->GetByteArrayElements(jData, NULL);
209 memcpy(nData, (char *)event + event->data_offset, event->data_size);
210 env->ReleaseByteArrayElements(jData, nData, 0);
211 }
212
Eric Laurentd3b82232014-07-30 08:57:39 -0700213 jobject jAudioFormat = NULL;
Eric Laurent39fcca02014-09-05 16:44:19 -0700214 if (event->trigger_in_data || event->capture_available) {
Eric Laurentd3b82232014-07-30 08:57:39 -0700215 jAudioFormat = env->NewObject(gAudioFormatClass,
216 gAudioFormatCstor,
217 audioFormatFromNative(event->audio_config.format),
218 event->audio_config.sample_rate,
219 inChannelMaskFromNative(event->audio_config.channel_mask));
220
221 }
Eric Laurent60b62bc2014-04-18 17:50:49 -0700222 if (event->type == SOUND_MODEL_TYPE_KEYPHRASE) {
223 struct sound_trigger_phrase_recognition_event *phraseEvent =
224 (struct sound_trigger_phrase_recognition_event *)event;
225
226 jobjectArray jExtras = env->NewObjectArray(phraseEvent->num_phrases,
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700227 gKeyphraseRecognitionExtraClass, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700228 if (jExtras == NULL) {
229 return;
230 }
231
232 for (size_t i = 0; i < phraseEvent->num_phrases; i++) {
Eric Laurent013f66b2014-07-06 16:35:00 -0700233 jobjectArray jConfidenceLevels = env->NewObjectArray(
234 phraseEvent->phrase_extras[i].num_levels,
235 gConfidenceLevelClass, NULL);
236
Eric Laurent60b62bc2014-04-18 17:50:49 -0700237 if (jConfidenceLevels == NULL) {
238 return;
239 }
Eric Laurent013f66b2014-07-06 16:35:00 -0700240 for (size_t j = 0; j < phraseEvent->phrase_extras[i].num_levels; j++) {
241 jobject jConfidenceLevel = env->NewObject(gConfidenceLevelClass,
242 gConfidenceLevelCstor,
243 phraseEvent->phrase_extras[i].levels[j].user_id,
244 phraseEvent->phrase_extras[i].levels[j].level);
245 env->SetObjectArrayElement(jConfidenceLevels, j, jConfidenceLevel);
246 env->DeleteLocalRef(jConfidenceLevel);
247 }
248
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700249 jobject jNewExtra = env->NewObject(gKeyphraseRecognitionExtraClass,
250 gKeyphraseRecognitionExtraCstor,
Eric Laurent013f66b2014-07-06 16:35:00 -0700251 phraseEvent->phrase_extras[i].id,
252 phraseEvent->phrase_extras[i].recognition_modes,
Eric Laurentd3b82232014-07-30 08:57:39 -0700253 phraseEvent->phrase_extras[i].confidence_level,
Eric Laurent013f66b2014-07-06 16:35:00 -0700254 jConfidenceLevels);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700255
256 if (jNewExtra == NULL) {
257 return;
258 }
259 env->SetObjectArrayElement(jExtras, i, jNewExtra);
Eric Laurent013f66b2014-07-06 16:35:00 -0700260 env->DeleteLocalRef(jNewExtra);
261 env->DeleteLocalRef(jConfidenceLevels);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700262 }
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700263 jEvent = env->NewObject(gKeyphraseRecognitionEventClass, gKeyphraseRecognitionEventCstor,
Eric Laurent60b62bc2014-04-18 17:50:49 -0700264 event->status, event->model, event->capture_available,
Eric Laurentd3b82232014-07-30 08:57:39 -0700265 event->capture_session, event->capture_delay_ms,
266 event->capture_preamble_ms, event->trigger_in_data,
267 jAudioFormat, jData, jExtras);
Eric Laurent8f89feb2014-10-29 15:52:43 -0700268 env->DeleteLocalRef(jExtras);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700269 } else {
270 jEvent = env->NewObject(gRecognitionEventClass, gRecognitionEventCstor,
271 event->status, event->model, event->capture_available,
Eric Laurent013f66b2014-07-06 16:35:00 -0700272 event->capture_session, event->capture_delay_ms,
Eric Laurentd3b82232014-07-30 08:57:39 -0700273 event->capture_preamble_ms, event->trigger_in_data,
274 jAudioFormat, jData);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700275 }
276
Eric Laurent8f89feb2014-10-29 15:52:43 -0700277 if (jAudioFormat != NULL) {
278 env->DeleteLocalRef(jAudioFormat);
279 }
280 if (jData != NULL) {
281 env->DeleteLocalRef(jData);
282 }
Eric Laurent60b62bc2014-04-18 17:50:49 -0700283
284 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
285 SOUNDTRIGGER_EVENT_RECOGNITION, 0, 0, jEvent);
Eric Laurentd3b82232014-07-30 08:57:39 -0700286
287 env->DeleteLocalRef(jEvent);
288 if (env->ExceptionCheck()) {
289 ALOGW("An exception occurred while notifying an event.");
290 env->ExceptionClear();
291 }
292}
293
294void JNISoundTriggerCallback::onSoundModelEvent(struct sound_trigger_model_event *event)
295{
296 JNIEnv *env = AndroidRuntime::getJNIEnv();
297 jobject jEvent = NULL;
298 jbyteArray jData = NULL;
299
300 if (event->data_size) {
301 jData = env->NewByteArray(event->data_size);
302 jbyte *nData = env->GetByteArrayElements(jData, NULL);
303 memcpy(nData, (char *)event + event->data_offset, event->data_size);
304 env->ReleaseByteArrayElements(jData, nData, 0);
305 }
306
307 jEvent = env->NewObject(gSoundModelEventClass, gSoundModelEventCstor,
308 event->status, event->model, jData);
309
310 env->DeleteLocalRef(jData);
311 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
312 SOUNDTRIGGER_EVENT_SOUNDMODEL, 0, 0, jEvent);
313 env->DeleteLocalRef(jEvent);
314 if (env->ExceptionCheck()) {
315 ALOGW("An exception occurred while notifying an event.");
316 env->ExceptionClear();
317 }
318}
319
320void JNISoundTriggerCallback::onServiceStateChange(sound_trigger_service_state_t state)
321{
322 JNIEnv *env = AndroidRuntime::getJNIEnv();
323 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
324 SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE, state, 0, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700325 if (env->ExceptionCheck()) {
326 ALOGW("An exception occurred while notifying an event.");
327 env->ExceptionClear();
328 }
329}
330
331void JNISoundTriggerCallback::onServiceDied()
332{
333 JNIEnv *env = AndroidRuntime::getJNIEnv();
334
335 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
336 SOUNDTRIGGER_EVENT_SERVICE_DIED, 0, 0, NULL);
337 if (env->ExceptionCheck()) {
338 ALOGW("An exception occurred while notifying an event.");
339 env->ExceptionClear();
340 }
341}
342
343// ----------------------------------------------------------------------------
344
345static sp<SoundTrigger> getSoundTrigger(JNIEnv* env, jobject thiz)
346{
347 Mutex::Autolock l(gLock);
348 SoundTrigger* const st = (SoundTrigger*)env->GetLongField(thiz,
349 gModuleFields.mNativeContext);
350 return sp<SoundTrigger>(st);
351}
352
353static sp<SoundTrigger> setSoundTrigger(JNIEnv* env, jobject thiz, const sp<SoundTrigger>& module)
354{
355 Mutex::Autolock l(gLock);
356 sp<SoundTrigger> old = (SoundTrigger*)env->GetLongField(thiz,
357 gModuleFields.mNativeContext);
358 if (module.get()) {
359 module->incStrong((void*)setSoundTrigger);
360 }
361 if (old != 0) {
362 old->decStrong((void*)setSoundTrigger);
363 }
364 env->SetLongField(thiz, gModuleFields.mNativeContext, (jlong)module.get());
365 return old;
366}
367
368
369static jint
370android_hardware_SoundTrigger_listModules(JNIEnv *env, jobject clazz,
371 jobject jModules)
372{
373 ALOGV("listModules");
374
375 if (jModules == NULL) {
376 ALOGE("listModules NULL AudioPatch ArrayList");
377 return SOUNDTRIGGER_STATUS_BAD_VALUE;
378 }
379 if (!env->IsInstanceOf(jModules, gArrayListClass)) {
380 ALOGE("listModules not an arraylist");
381 return SOUNDTRIGGER_STATUS_BAD_VALUE;
382 }
383
384 unsigned int numModules = 0;
385 struct sound_trigger_module_descriptor *nModules = NULL;
386
387 status_t status = SoundTrigger::listModules(nModules, &numModules);
388 if (status != NO_ERROR || numModules == 0) {
389 return (jint)status;
390 }
391
392 nModules = (struct sound_trigger_module_descriptor *)
393 calloc(numModules, sizeof(struct sound_trigger_module_descriptor));
394
395 status = SoundTrigger::listModules(nModules, &numModules);
396 ALOGV("listModules SoundTrigger::listModules status %d numModules %d", status, numModules);
397
398 if (status != NO_ERROR) {
399 numModules = 0;
400 }
401
402 for (size_t i = 0; i < numModules; i++) {
403 char str[SOUND_TRIGGER_MAX_STRING_LEN];
404
405 jstring implementor = env->NewStringUTF(nModules[i].properties.implementor);
406 jstring description = env->NewStringUTF(nModules[i].properties.description);
407 SoundTrigger::guidToString(&nModules[i].properties.uuid,
408 str,
409 SOUND_TRIGGER_MAX_STRING_LEN);
410 jstring uuid = env->NewStringUTF(str);
411
Eric Laurentd3b82232014-07-30 08:57:39 -0700412 ALOGV("listModules module %zu id %d description %s maxSoundModels %d",
Eric Laurent60b62bc2014-04-18 17:50:49 -0700413 i, nModules[i].handle, nModules[i].properties.description,
414 nModules[i].properties.max_sound_models);
415
416 jobject newModuleDesc = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
417 nModules[i].handle,
418 implementor, description, uuid,
419 nModules[i].properties.version,
420 nModules[i].properties.max_sound_models,
421 nModules[i].properties.max_key_phrases,
422 nModules[i].properties.max_users,
423 nModules[i].properties.recognition_modes,
424 nModules[i].properties.capture_transition,
425 nModules[i].properties.max_buffer_ms,
426 nModules[i].properties.concurrent_capture,
Eric Laurentd3b82232014-07-30 08:57:39 -0700427 nModules[i].properties.power_consumption_mw,
428 nModules[i].properties.trigger_in_event);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700429
430 env->DeleteLocalRef(implementor);
431 env->DeleteLocalRef(description);
432 env->DeleteLocalRef(uuid);
433 if (newModuleDesc == NULL) {
434 status = SOUNDTRIGGER_STATUS_ERROR;
435 goto exit;
436 }
437 env->CallBooleanMethod(jModules, gArrayListMethods.add, newModuleDesc);
438 }
439
440exit:
441 free(nModules);
442 return (jint) status;
443}
444
445static void
446android_hardware_SoundTrigger_setup(JNIEnv *env, jobject thiz, jobject weak_this)
447{
448 ALOGV("setup");
449
450 sp<JNISoundTriggerCallback> callback = new JNISoundTriggerCallback(env, thiz, weak_this);
451
452 sound_trigger_module_handle_t handle =
453 (sound_trigger_module_handle_t)env->GetIntField(thiz, gModuleFields.mId);
454
455 sp<SoundTrigger> module = SoundTrigger::attach(handle, callback);
456 if (module == 0) {
457 return;
458 }
459
460 setSoundTrigger(env, thiz, module);
461}
462
463static void
464android_hardware_SoundTrigger_detach(JNIEnv *env, jobject thiz)
465{
466 ALOGV("detach");
467 sp<SoundTrigger> module = setSoundTrigger(env, thiz, 0);
468 ALOGV("detach module %p", module.get());
469 if (module != 0) {
470 ALOGV("detach module->detach()");
471 module->detach();
472 }
473}
474
475static void
476android_hardware_SoundTrigger_finalize(JNIEnv *env, jobject thiz)
477{
478 ALOGV("finalize");
479 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
480 if (module != 0) {
481 ALOGW("SoundTrigger finalized without being detached");
482 }
483 android_hardware_SoundTrigger_detach(env, thiz);
484}
485
486static jint
487android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
488 jobject jSoundModel, jintArray jHandle)
489{
490 jint status = SOUNDTRIGGER_STATUS_OK;
Eric Laurent013f66b2014-07-06 16:35:00 -0700491 jbyte *nData = NULL;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700492 struct sound_trigger_sound_model *nSoundModel;
493 jbyteArray jData;
494 sp<MemoryDealer> memoryDealer;
495 sp<IMemory> memory;
496 size_t size;
497 sound_model_handle_t handle;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700498 jobject jUuid;
499 jstring jUuidString;
500 const char *nUuidString;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700501
502 ALOGV("loadSoundModel");
503 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
504 if (module == NULL) {
505 return SOUNDTRIGGER_STATUS_ERROR;
506 }
507 if (jHandle == NULL) {
508 return SOUNDTRIGGER_STATUS_BAD_VALUE;
509 }
510 jsize jHandleLen = env->GetArrayLength(jHandle);
511 if (jHandleLen == 0) {
512 return SOUNDTRIGGER_STATUS_BAD_VALUE;
513 }
514 jint *nHandle = env->GetIntArrayElements(jHandle, NULL);
515 if (nHandle == NULL) {
516 return SOUNDTRIGGER_STATUS_ERROR;
517 }
518 if (!env->IsInstanceOf(jSoundModel, gSoundModelClass)) {
519 status = SOUNDTRIGGER_STATUS_BAD_VALUE;
520 goto exit;
521 }
522 size_t offset;
523 sound_trigger_sound_model_type_t type;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700524 if (env->IsInstanceOf(jSoundModel, gKeyphraseSoundModelClass)) {
Eric Laurent60b62bc2014-04-18 17:50:49 -0700525 offset = sizeof(struct sound_trigger_phrase_sound_model);
526 type = SOUND_MODEL_TYPE_KEYPHRASE;
527 } else {
528 offset = sizeof(struct sound_trigger_sound_model);
529 type = SOUND_MODEL_TYPE_UNKNOWN;
530 }
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700531
532 jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.uuid);
533 jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
534 nUuidString = env->GetStringUTFChars(jUuidString, NULL);
535 sound_trigger_uuid_t nUuid;
536 SoundTrigger::stringToGuid(nUuidString, &nUuid);
537 env->ReleaseStringUTFChars(jUuidString, nUuidString);
538 env->DeleteLocalRef(jUuidString);
539
Eric Laurentd3b82232014-07-30 08:57:39 -0700540 sound_trigger_uuid_t nVendorUuid;
541 jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.vendorUuid);
542 if (jUuid != NULL) {
543 jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
544 nUuidString = env->GetStringUTFChars(jUuidString, NULL);
545 SoundTrigger::stringToGuid(nUuidString, &nVendorUuid);
546 env->ReleaseStringUTFChars(jUuidString, nUuidString);
547 env->DeleteLocalRef(jUuidString);
548 } else {
549 SoundTrigger::stringToGuid("00000000-0000-0000-0000-000000000000", &nVendorUuid);
550 }
551
Eric Laurent60b62bc2014-04-18 17:50:49 -0700552 jData = (jbyteArray)env->GetObjectField(jSoundModel, gSoundModelFields.data);
553 if (jData == NULL) {
554 status = SOUNDTRIGGER_STATUS_BAD_VALUE;
555 goto exit;
556 }
557 size = env->GetArrayLength(jData);
558
Eric Laurent013f66b2014-07-06 16:35:00 -0700559 nData = env->GetByteArrayElements(jData, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700560 if (jData == NULL) {
561 status = SOUNDTRIGGER_STATUS_ERROR;
562 goto exit;
563 }
564
565 memoryDealer = new MemoryDealer(offset + size, "SoundTrigge-JNI::LoadModel");
566 if (memoryDealer == 0) {
567 status = SOUNDTRIGGER_STATUS_ERROR;
568 goto exit;
569 }
570 memory = memoryDealer->allocate(offset + size);
571 if (memory == 0 || memory->pointer() == NULL) {
572 status = SOUNDTRIGGER_STATUS_ERROR;
573 goto exit;
574 }
575
576 nSoundModel = (struct sound_trigger_sound_model *)memory->pointer();
577
578 nSoundModel->type = type;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700579 nSoundModel->uuid = nUuid;
Eric Laurentd3b82232014-07-30 08:57:39 -0700580 nSoundModel->vendor_uuid = nVendorUuid;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700581 nSoundModel->data_size = size;
582 nSoundModel->data_offset = offset;
583 memcpy((char *)nSoundModel + offset, nData, size);
584 if (type == SOUND_MODEL_TYPE_KEYPHRASE) {
585 struct sound_trigger_phrase_sound_model *phraseModel =
586 (struct sound_trigger_phrase_sound_model *)nSoundModel;
587
588 jobjectArray jPhrases =
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700589 (jobjectArray)env->GetObjectField(jSoundModel, gKeyphraseSoundModelFields.keyphrases);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700590 if (jPhrases == NULL) {
591 status = SOUNDTRIGGER_STATUS_BAD_VALUE;
592 goto exit;
593 }
594
595 size_t numPhrases = env->GetArrayLength(jPhrases);
596 phraseModel->num_phrases = numPhrases;
Eric Laurentd3b82232014-07-30 08:57:39 -0700597 ALOGV("loadSoundModel numPhrases %zu", numPhrases);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700598 for (size_t i = 0; i < numPhrases; i++) {
599 jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700600 phraseModel->phrases[i].id =
601 env->GetIntField(jPhrase,gKeyphraseFields.id);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700602 phraseModel->phrases[i].recognition_mode =
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700603 env->GetIntField(jPhrase,gKeyphraseFields.recognitionModes);
Eric Laurent013f66b2014-07-06 16:35:00 -0700604
605 jintArray jUsers = (jintArray)env->GetObjectField(jPhrase, gKeyphraseFields.users);
606 phraseModel->phrases[i].num_users = env->GetArrayLength(jUsers);
607 jint *nUsers = env->GetIntArrayElements(jUsers, NULL);
608 memcpy(phraseModel->phrases[i].users,
609 nUsers,
610 phraseModel->phrases[i].num_users * sizeof(int));
611 env->ReleaseIntArrayElements(jUsers, nUsers, 0);
612 env->DeleteLocalRef(jUsers);
613
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700614 jstring jLocale = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.locale);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700615 const char *nLocale = env->GetStringUTFChars(jLocale, NULL);
616 strncpy(phraseModel->phrases[i].locale,
617 nLocale,
618 SOUND_TRIGGER_MAX_LOCALE_LEN);
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700619 jstring jText = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.text);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700620 const char *nText = env->GetStringUTFChars(jText, NULL);
621 strncpy(phraseModel->phrases[i].text,
622 nText,
623 SOUND_TRIGGER_MAX_STRING_LEN);
624
625 env->ReleaseStringUTFChars(jLocale, nLocale);
626 env->DeleteLocalRef(jLocale);
627 env->ReleaseStringUTFChars(jText, nText);
628 env->DeleteLocalRef(jText);
Eric Laurentd3b82232014-07-30 08:57:39 -0700629 ALOGV("loadSoundModel phrases %zu text %s locale %s",
Eric Laurent60b62bc2014-04-18 17:50:49 -0700630 i, phraseModel->phrases[i].text, phraseModel->phrases[i].locale);
Eric Laurent013f66b2014-07-06 16:35:00 -0700631 env->DeleteLocalRef(jPhrase);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700632 }
633 env->DeleteLocalRef(jPhrases);
634 }
635 status = module->loadSoundModel(memory, &handle);
636 ALOGV("loadSoundModel status %d handle %d", status, handle);
637
638exit:
639 if (nHandle != NULL) {
640 nHandle[0] = (jint)handle;
641 env->ReleaseIntArrayElements(jHandle, nHandle, NULL);
642 }
643 if (nData != NULL) {
Eric Laurent013f66b2014-07-06 16:35:00 -0700644 env->ReleaseByteArrayElements(jData, nData, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700645 }
646 return status;
647}
648
649static jint
650android_hardware_SoundTrigger_unloadSoundModel(JNIEnv *env, jobject thiz,
651 jint jHandle)
652{
653 jint status = SOUNDTRIGGER_STATUS_OK;
654 ALOGV("unloadSoundModel");
655 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
656 if (module == NULL) {
657 return SOUNDTRIGGER_STATUS_ERROR;
658 }
659 status = module->unloadSoundModel((sound_model_handle_t)jHandle);
660
661 return status;
662}
663
664static jint
665android_hardware_SoundTrigger_startRecognition(JNIEnv *env, jobject thiz,
Eric Laurent013f66b2014-07-06 16:35:00 -0700666 jint jHandle, jobject jConfig)
Eric Laurent60b62bc2014-04-18 17:50:49 -0700667{
668 jint status = SOUNDTRIGGER_STATUS_OK;
669 ALOGV("startRecognition");
670 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
671 if (module == NULL) {
672 return SOUNDTRIGGER_STATUS_ERROR;
673 }
Eric Laurent013f66b2014-07-06 16:35:00 -0700674
675 if (!env->IsInstanceOf(jConfig, gRecognitionConfigClass)) {
676 return SOUNDTRIGGER_STATUS_BAD_VALUE;
677 }
678
679 jbyteArray jData = (jbyteArray)env->GetObjectField(jConfig, gRecognitionConfigFields.data);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700680 jsize dataSize = 0;
Eric Laurent013f66b2014-07-06 16:35:00 -0700681 jbyte *nData = NULL;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700682 if (jData != NULL) {
683 dataSize = env->GetArrayLength(jData);
684 if (dataSize == 0) {
685 return SOUNDTRIGGER_STATUS_BAD_VALUE;
686 }
Eric Laurent013f66b2014-07-06 16:35:00 -0700687 nData = env->GetByteArrayElements(jData, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700688 if (nData == NULL) {
689 return SOUNDTRIGGER_STATUS_ERROR;
690 }
Eric Laurent60b62bc2014-04-18 17:50:49 -0700691 }
692
Eric Laurent013f66b2014-07-06 16:35:00 -0700693 size_t totalSize = sizeof(struct sound_trigger_recognition_config) + dataSize;
694 sp<MemoryDealer> memoryDealer =
695 new MemoryDealer(totalSize, "SoundTrigge-JNI::StartRecognition");
696 if (memoryDealer == 0) {
697 return SOUNDTRIGGER_STATUS_ERROR;
698 }
699 sp<IMemory> memory = memoryDealer->allocate(totalSize);
700 if (memory == 0 || memory->pointer() == NULL) {
701 return SOUNDTRIGGER_STATUS_ERROR;
702 }
703 if (dataSize != 0) {
704 memcpy((char *)memory->pointer() + sizeof(struct sound_trigger_recognition_config),
705 nData,
706 dataSize);
707 env->ReleaseByteArrayElements(jData, nData, 0);
708 }
709 env->DeleteLocalRef(jData);
710 struct sound_trigger_recognition_config *config =
711 (struct sound_trigger_recognition_config *)memory->pointer();
712 config->data_size = dataSize;
713 config->data_offset = sizeof(struct sound_trigger_recognition_config);
714 config->capture_requested = env->GetIntField(jConfig,
715 gRecognitionConfigFields.captureRequested);
716
717 config->num_phrases = 0;
718 jobjectArray jPhrases =
719 (jobjectArray)env->GetObjectField(jConfig, gRecognitionConfigFields.keyphrases);
720 if (jPhrases != NULL) {
721 config->num_phrases = env->GetArrayLength(jPhrases);
722 }
723 ALOGV("startRecognition num phrases %d", config->num_phrases);
724 for (size_t i = 0; i < config->num_phrases; i++) {
725 jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
726 config->phrases[i].id = env->GetIntField(jPhrase,
727 gKeyphraseRecognitionExtraFields.id);
728 config->phrases[i].recognition_modes = env->GetIntField(jPhrase,
729 gKeyphraseRecognitionExtraFields.recognitionModes);
Eric Laurentd3b82232014-07-30 08:57:39 -0700730 config->phrases[i].confidence_level = env->GetIntField(jPhrase,
731 gKeyphraseRecognitionExtraFields.coarseConfidenceLevel);
Eric Laurent013f66b2014-07-06 16:35:00 -0700732 config->phrases[i].num_levels = 0;
733 jobjectArray jConfidenceLevels = (jobjectArray)env->GetObjectField(jPhrase,
734 gKeyphraseRecognitionExtraFields.confidenceLevels);
735 if (jConfidenceLevels != NULL) {
736 config->phrases[i].num_levels = env->GetArrayLength(jConfidenceLevels);
737 }
Eric Laurentd3b82232014-07-30 08:57:39 -0700738 ALOGV("startRecognition phrase %zu num_levels %d", i, config->phrases[i].num_levels);
Eric Laurent013f66b2014-07-06 16:35:00 -0700739 for (size_t j = 0; j < config->phrases[i].num_levels; j++) {
740 jobject jConfidenceLevel = env->GetObjectArrayElement(jConfidenceLevels, j);
741 config->phrases[i].levels[j].user_id = env->GetIntField(jConfidenceLevel,
742 gConfidenceLevelFields.userId);
743 config->phrases[i].levels[j].level = env->GetIntField(jConfidenceLevel,
744 gConfidenceLevelFields.confidenceLevel);
745 env->DeleteLocalRef(jConfidenceLevel);
746 }
Eric Laurentd3b82232014-07-30 08:57:39 -0700747 ALOGV("startRecognition phrases %zu", i);
Eric Laurent013f66b2014-07-06 16:35:00 -0700748 env->DeleteLocalRef(jConfidenceLevels);
749 env->DeleteLocalRef(jPhrase);
750 }
751 env->DeleteLocalRef(jPhrases);
752
Eric Laurent60b62bc2014-04-18 17:50:49 -0700753 status = module->startRecognition(jHandle, memory);
754 return status;
755}
756
757static jint
758android_hardware_SoundTrigger_stopRecognition(JNIEnv *env, jobject thiz,
759 jint jHandle)
760{
761 jint status = SOUNDTRIGGER_STATUS_OK;
762 ALOGV("stopRecognition");
763 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
764 if (module == NULL) {
765 return SOUNDTRIGGER_STATUS_ERROR;
766 }
767 status = module->stopRecognition(jHandle);
768 return status;
769}
770
Daniel Micay76f6a862015-09-19 17:31:01 -0400771static const JNINativeMethod gMethods[] = {
Eric Laurent60b62bc2014-04-18 17:50:49 -0700772 {"listModules",
773 "(Ljava/util/ArrayList;)I",
774 (void *)android_hardware_SoundTrigger_listModules},
775};
776
777
Daniel Micay76f6a862015-09-19 17:31:01 -0400778static const JNINativeMethod gModuleMethods[] = {
Eric Laurent60b62bc2014-04-18 17:50:49 -0700779 {"native_setup",
780 "(Ljava/lang/Object;)V",
781 (void *)android_hardware_SoundTrigger_setup},
782 {"native_finalize",
783 "()V",
784 (void *)android_hardware_SoundTrigger_finalize},
785 {"detach",
786 "()V",
787 (void *)android_hardware_SoundTrigger_detach},
788 {"loadSoundModel",
789 "(Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;[I)I",
790 (void *)android_hardware_SoundTrigger_loadSoundModel},
791 {"unloadSoundModel",
792 "(I)I",
793 (void *)android_hardware_SoundTrigger_unloadSoundModel},
794 {"startRecognition",
Eric Laurent013f66b2014-07-06 16:35:00 -0700795 "(ILandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;)I",
Eric Laurent60b62bc2014-04-18 17:50:49 -0700796 (void *)android_hardware_SoundTrigger_startRecognition},
797 {"stopRecognition",
798 "(I)I",
799 (void *)android_hardware_SoundTrigger_stopRecognition},
800};
801
802int register_android_hardware_SoundTrigger(JNIEnv *env)
803{
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800804 jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
805 gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
806 gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700807
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800808 jclass uuidClass = FindClassOrDie(env, "java/util/UUID");
809 gUUIDClass = MakeGlobalRefOrDie(env, uuidClass);
810 gUUIDMethods.toString = GetMethodIDOrDie(env, uuidClass, "toString", "()Ljava/lang/String;");
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700811
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800812 jclass lClass = FindClassOrDie(env, kSoundTriggerClassPathName);
813 gSoundTriggerClass = MakeGlobalRefOrDie(env, lClass);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700814
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800815 jclass moduleClass = FindClassOrDie(env, kModuleClassPathName);
816 gModuleClass = MakeGlobalRefOrDie(env, moduleClass);
817 gPostEventFromNative = GetStaticMethodIDOrDie(env, moduleClass, "postEventFromNative",
818 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
819 gModuleFields.mNativeContext = GetFieldIDOrDie(env, moduleClass, "mNativeContext", "J");
820 gModuleFields.mId = GetFieldIDOrDie(env, moduleClass, "mId", "I");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700821
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800822 jclass modulePropertiesClass = FindClassOrDie(env, kModulePropertiesClassPathName);
823 gModulePropertiesClass = MakeGlobalRefOrDie(env, modulePropertiesClass);
824 gModulePropertiesCstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>",
825 "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700826
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800827 jclass soundModelClass = FindClassOrDie(env, kSoundModelClassPathName);
828 gSoundModelClass = MakeGlobalRefOrDie(env, soundModelClass);
829 gSoundModelFields.uuid = GetFieldIDOrDie(env, soundModelClass, "uuid", "Ljava/util/UUID;");
830 gSoundModelFields.vendorUuid = GetFieldIDOrDie(env, soundModelClass, "vendorUuid",
831 "Ljava/util/UUID;");
832 gSoundModelFields.data = GetFieldIDOrDie(env, soundModelClass, "data", "[B");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700833
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800834 jclass keyphraseClass = FindClassOrDie(env, kKeyphraseClassPathName);
835 gKeyphraseClass = MakeGlobalRefOrDie(env, keyphraseClass);
836 gKeyphraseFields.id = GetFieldIDOrDie(env, keyphraseClass, "id", "I");
837 gKeyphraseFields.recognitionModes = GetFieldIDOrDie(env, keyphraseClass, "recognitionModes",
838 "I");
839 gKeyphraseFields.locale = GetFieldIDOrDie(env, keyphraseClass, "locale", "Ljava/lang/String;");
840 gKeyphraseFields.text = GetFieldIDOrDie(env, keyphraseClass, "text", "Ljava/lang/String;");
841 gKeyphraseFields.users = GetFieldIDOrDie(env, keyphraseClass, "users", "[I");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700842
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800843 jclass keyphraseSoundModelClass = FindClassOrDie(env, kKeyphraseSoundModelClassPathName);
844 gKeyphraseSoundModelClass = MakeGlobalRefOrDie(env, keyphraseSoundModelClass);
845 gKeyphraseSoundModelFields.keyphrases = GetFieldIDOrDie(env, keyphraseSoundModelClass,
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700846 "keyphrases",
847 "[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700848
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800849 jclass recognitionEventClass = FindClassOrDie(env, kRecognitionEventClassPathName);
850 gRecognitionEventClass = MakeGlobalRefOrDie(env, recognitionEventClass);
851 gRecognitionEventCstor = GetMethodIDOrDie(env, recognitionEventClass, "<init>",
Eric Laurentd3b82232014-07-30 08:57:39 -0700852 "(IIZIIIZLandroid/media/AudioFormat;[B)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700853
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800854 jclass keyphraseRecognitionEventClass = FindClassOrDie(env,
855 kKeyphraseRecognitionEventClassPathName);
856 gKeyphraseRecognitionEventClass = MakeGlobalRefOrDie(env, keyphraseRecognitionEventClass);
857 gKeyphraseRecognitionEventCstor = GetMethodIDOrDie(env, keyphraseRecognitionEventClass, "<init>",
Eric Laurentd3b82232014-07-30 08:57:39 -0700858 "(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700859
860
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800861 jclass keyRecognitionConfigClass = FindClassOrDie(env, kRecognitionConfigClassPathName);
862 gRecognitionConfigClass = MakeGlobalRefOrDie(env, keyRecognitionConfigClass);
863 gRecognitionConfigFields.captureRequested = GetFieldIDOrDie(env, keyRecognitionConfigClass,
864 "captureRequested", "Z");
865 gRecognitionConfigFields.keyphrases = GetFieldIDOrDie(env, keyRecognitionConfigClass,
866 "keyphrases", "[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;");
867 gRecognitionConfigFields.data = GetFieldIDOrDie(env, keyRecognitionConfigClass, "data", "[B");
Eric Laurent013f66b2014-07-06 16:35:00 -0700868
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800869 jclass keyphraseRecognitionExtraClass = FindClassOrDie(env,
870 kKeyphraseRecognitionExtraClassPathName);
871 gKeyphraseRecognitionExtraClass = MakeGlobalRefOrDie(env, keyphraseRecognitionExtraClass);
872 gKeyphraseRecognitionExtraCstor = GetMethodIDOrDie(env, keyphraseRecognitionExtraClass,
873 "<init>", "(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V");
874 gKeyphraseRecognitionExtraFields.id = GetFieldIDOrDie(env, gKeyphraseRecognitionExtraClass,
875 "id", "I");
876 gKeyphraseRecognitionExtraFields.recognitionModes = GetFieldIDOrDie(env,
877 gKeyphraseRecognitionExtraClass, "recognitionModes", "I");
878 gKeyphraseRecognitionExtraFields.coarseConfidenceLevel = GetFieldIDOrDie(env,
879 gKeyphraseRecognitionExtraClass, "coarseConfidenceLevel", "I");
880 gKeyphraseRecognitionExtraFields.confidenceLevels = GetFieldIDOrDie(env,
881 gKeyphraseRecognitionExtraClass, "confidenceLevels",
882 "[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;");
Eric Laurent013f66b2014-07-06 16:35:00 -0700883
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800884 jclass confidenceLevelClass = FindClassOrDie(env, kConfidenceLevelClassPathName);
885 gConfidenceLevelClass = MakeGlobalRefOrDie(env, confidenceLevelClass);
886 gConfidenceLevelCstor = GetMethodIDOrDie(env, confidenceLevelClass, "<init>", "(II)V");
887 gConfidenceLevelFields.userId = GetFieldIDOrDie(env, confidenceLevelClass, "userId", "I");
888 gConfidenceLevelFields.confidenceLevel = GetFieldIDOrDie(env, confidenceLevelClass,
Eric Laurent013f66b2014-07-06 16:35:00 -0700889 "confidenceLevel", "I");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700890
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800891 jclass audioFormatClass = FindClassOrDie(env, kAudioFormatClassPathName);
892 gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
893 gAudioFormatCstor = GetMethodIDOrDie(env, audioFormatClass, "<init>", "(III)V");
Eric Laurentd3b82232014-07-30 08:57:39 -0700894
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800895 jclass soundModelEventClass = FindClassOrDie(env, kSoundModelEventClassPathName);
896 gSoundModelEventClass = MakeGlobalRefOrDie(env, soundModelEventClass);
897 gSoundModelEventCstor = GetMethodIDOrDie(env, soundModelEventClass, "<init>", "(II[B)V");
Eric Laurentd3b82232014-07-30 08:57:39 -0700898
899
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800900 RegisterMethodsOrDie(env, kSoundTriggerClassPathName, gMethods, NELEM(gMethods));
901 return RegisterMethodsOrDie(env, kModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));
Eric Laurent60b62bc2014-04-18 17:50:49 -0700902}