blob: f0d7a35c95142f03bf62d3a26275ad92a5eb7710 [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"
24#include "android_runtime/AndroidRuntime.h"
25#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;
214 if (event->trigger_in_data) {
215 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);
268 env->DeleteLocalRef(jAudioFormat);
269 env->DeleteLocalRef(jData);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700270 } else {
271 jEvent = env->NewObject(gRecognitionEventClass, gRecognitionEventCstor,
272 event->status, event->model, event->capture_available,
Eric Laurent013f66b2014-07-06 16:35:00 -0700273 event->capture_session, event->capture_delay_ms,
Eric Laurentd3b82232014-07-30 08:57:39 -0700274 event->capture_preamble_ms, event->trigger_in_data,
275 jAudioFormat, jData);
276 env->DeleteLocalRef(jAudioFormat);
277 env->DeleteLocalRef(jData);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700278 }
279
280
281 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
282 SOUNDTRIGGER_EVENT_RECOGNITION, 0, 0, jEvent);
Eric Laurentd3b82232014-07-30 08:57:39 -0700283
284 env->DeleteLocalRef(jEvent);
285 if (env->ExceptionCheck()) {
286 ALOGW("An exception occurred while notifying an event.");
287 env->ExceptionClear();
288 }
289}
290
291void JNISoundTriggerCallback::onSoundModelEvent(struct sound_trigger_model_event *event)
292{
293 JNIEnv *env = AndroidRuntime::getJNIEnv();
294 jobject jEvent = NULL;
295 jbyteArray jData = NULL;
296
297 if (event->data_size) {
298 jData = env->NewByteArray(event->data_size);
299 jbyte *nData = env->GetByteArrayElements(jData, NULL);
300 memcpy(nData, (char *)event + event->data_offset, event->data_size);
301 env->ReleaseByteArrayElements(jData, nData, 0);
302 }
303
304 jEvent = env->NewObject(gSoundModelEventClass, gSoundModelEventCstor,
305 event->status, event->model, jData);
306
307 env->DeleteLocalRef(jData);
308 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
309 SOUNDTRIGGER_EVENT_SOUNDMODEL, 0, 0, jEvent);
310 env->DeleteLocalRef(jEvent);
311 if (env->ExceptionCheck()) {
312 ALOGW("An exception occurred while notifying an event.");
313 env->ExceptionClear();
314 }
315}
316
317void JNISoundTriggerCallback::onServiceStateChange(sound_trigger_service_state_t state)
318{
319 JNIEnv *env = AndroidRuntime::getJNIEnv();
320 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
321 SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE, state, 0, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700322 if (env->ExceptionCheck()) {
323 ALOGW("An exception occurred while notifying an event.");
324 env->ExceptionClear();
325 }
326}
327
328void JNISoundTriggerCallback::onServiceDied()
329{
330 JNIEnv *env = AndroidRuntime::getJNIEnv();
331
332 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
333 SOUNDTRIGGER_EVENT_SERVICE_DIED, 0, 0, NULL);
334 if (env->ExceptionCheck()) {
335 ALOGW("An exception occurred while notifying an event.");
336 env->ExceptionClear();
337 }
338}
339
340// ----------------------------------------------------------------------------
341
342static sp<SoundTrigger> getSoundTrigger(JNIEnv* env, jobject thiz)
343{
344 Mutex::Autolock l(gLock);
345 SoundTrigger* const st = (SoundTrigger*)env->GetLongField(thiz,
346 gModuleFields.mNativeContext);
347 return sp<SoundTrigger>(st);
348}
349
350static sp<SoundTrigger> setSoundTrigger(JNIEnv* env, jobject thiz, const sp<SoundTrigger>& module)
351{
352 Mutex::Autolock l(gLock);
353 sp<SoundTrigger> old = (SoundTrigger*)env->GetLongField(thiz,
354 gModuleFields.mNativeContext);
355 if (module.get()) {
356 module->incStrong((void*)setSoundTrigger);
357 }
358 if (old != 0) {
359 old->decStrong((void*)setSoundTrigger);
360 }
361 env->SetLongField(thiz, gModuleFields.mNativeContext, (jlong)module.get());
362 return old;
363}
364
365
366static jint
367android_hardware_SoundTrigger_listModules(JNIEnv *env, jobject clazz,
368 jobject jModules)
369{
370 ALOGV("listModules");
371
372 if (jModules == NULL) {
373 ALOGE("listModules NULL AudioPatch ArrayList");
374 return SOUNDTRIGGER_STATUS_BAD_VALUE;
375 }
376 if (!env->IsInstanceOf(jModules, gArrayListClass)) {
377 ALOGE("listModules not an arraylist");
378 return SOUNDTRIGGER_STATUS_BAD_VALUE;
379 }
380
381 unsigned int numModules = 0;
382 struct sound_trigger_module_descriptor *nModules = NULL;
383
384 status_t status = SoundTrigger::listModules(nModules, &numModules);
385 if (status != NO_ERROR || numModules == 0) {
386 return (jint)status;
387 }
388
389 nModules = (struct sound_trigger_module_descriptor *)
390 calloc(numModules, sizeof(struct sound_trigger_module_descriptor));
391
392 status = SoundTrigger::listModules(nModules, &numModules);
393 ALOGV("listModules SoundTrigger::listModules status %d numModules %d", status, numModules);
394
395 if (status != NO_ERROR) {
396 numModules = 0;
397 }
398
399 for (size_t i = 0; i < numModules; i++) {
400 char str[SOUND_TRIGGER_MAX_STRING_LEN];
401
402 jstring implementor = env->NewStringUTF(nModules[i].properties.implementor);
403 jstring description = env->NewStringUTF(nModules[i].properties.description);
404 SoundTrigger::guidToString(&nModules[i].properties.uuid,
405 str,
406 SOUND_TRIGGER_MAX_STRING_LEN);
407 jstring uuid = env->NewStringUTF(str);
408
Eric Laurentd3b82232014-07-30 08:57:39 -0700409 ALOGV("listModules module %zu id %d description %s maxSoundModels %d",
Eric Laurent60b62bc2014-04-18 17:50:49 -0700410 i, nModules[i].handle, nModules[i].properties.description,
411 nModules[i].properties.max_sound_models);
412
413 jobject newModuleDesc = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
414 nModules[i].handle,
415 implementor, description, uuid,
416 nModules[i].properties.version,
417 nModules[i].properties.max_sound_models,
418 nModules[i].properties.max_key_phrases,
419 nModules[i].properties.max_users,
420 nModules[i].properties.recognition_modes,
421 nModules[i].properties.capture_transition,
422 nModules[i].properties.max_buffer_ms,
423 nModules[i].properties.concurrent_capture,
Eric Laurentd3b82232014-07-30 08:57:39 -0700424 nModules[i].properties.power_consumption_mw,
425 nModules[i].properties.trigger_in_event);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700426
427 env->DeleteLocalRef(implementor);
428 env->DeleteLocalRef(description);
429 env->DeleteLocalRef(uuid);
430 if (newModuleDesc == NULL) {
431 status = SOUNDTRIGGER_STATUS_ERROR;
432 goto exit;
433 }
434 env->CallBooleanMethod(jModules, gArrayListMethods.add, newModuleDesc);
435 }
436
437exit:
438 free(nModules);
439 return (jint) status;
440}
441
442static void
443android_hardware_SoundTrigger_setup(JNIEnv *env, jobject thiz, jobject weak_this)
444{
445 ALOGV("setup");
446
447 sp<JNISoundTriggerCallback> callback = new JNISoundTriggerCallback(env, thiz, weak_this);
448
449 sound_trigger_module_handle_t handle =
450 (sound_trigger_module_handle_t)env->GetIntField(thiz, gModuleFields.mId);
451
452 sp<SoundTrigger> module = SoundTrigger::attach(handle, callback);
453 if (module == 0) {
454 return;
455 }
456
457 setSoundTrigger(env, thiz, module);
458}
459
460static void
461android_hardware_SoundTrigger_detach(JNIEnv *env, jobject thiz)
462{
463 ALOGV("detach");
464 sp<SoundTrigger> module = setSoundTrigger(env, thiz, 0);
465 ALOGV("detach module %p", module.get());
466 if (module != 0) {
467 ALOGV("detach module->detach()");
468 module->detach();
469 }
470}
471
472static void
473android_hardware_SoundTrigger_finalize(JNIEnv *env, jobject thiz)
474{
475 ALOGV("finalize");
476 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
477 if (module != 0) {
478 ALOGW("SoundTrigger finalized without being detached");
479 }
480 android_hardware_SoundTrigger_detach(env, thiz);
481}
482
483static jint
484android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
485 jobject jSoundModel, jintArray jHandle)
486{
487 jint status = SOUNDTRIGGER_STATUS_OK;
Eric Laurent013f66b2014-07-06 16:35:00 -0700488 jbyte *nData = NULL;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700489 struct sound_trigger_sound_model *nSoundModel;
490 jbyteArray jData;
491 sp<MemoryDealer> memoryDealer;
492 sp<IMemory> memory;
493 size_t size;
494 sound_model_handle_t handle;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700495 jobject jUuid;
496 jstring jUuidString;
497 const char *nUuidString;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700498
499 ALOGV("loadSoundModel");
500 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
501 if (module == NULL) {
502 return SOUNDTRIGGER_STATUS_ERROR;
503 }
504 if (jHandle == NULL) {
505 return SOUNDTRIGGER_STATUS_BAD_VALUE;
506 }
507 jsize jHandleLen = env->GetArrayLength(jHandle);
508 if (jHandleLen == 0) {
509 return SOUNDTRIGGER_STATUS_BAD_VALUE;
510 }
511 jint *nHandle = env->GetIntArrayElements(jHandle, NULL);
512 if (nHandle == NULL) {
513 return SOUNDTRIGGER_STATUS_ERROR;
514 }
515 if (!env->IsInstanceOf(jSoundModel, gSoundModelClass)) {
516 status = SOUNDTRIGGER_STATUS_BAD_VALUE;
517 goto exit;
518 }
519 size_t offset;
520 sound_trigger_sound_model_type_t type;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700521 if (env->IsInstanceOf(jSoundModel, gKeyphraseSoundModelClass)) {
Eric Laurent60b62bc2014-04-18 17:50:49 -0700522 offset = sizeof(struct sound_trigger_phrase_sound_model);
523 type = SOUND_MODEL_TYPE_KEYPHRASE;
524 } else {
525 offset = sizeof(struct sound_trigger_sound_model);
526 type = SOUND_MODEL_TYPE_UNKNOWN;
527 }
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700528
529 jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.uuid);
530 jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
531 nUuidString = env->GetStringUTFChars(jUuidString, NULL);
532 sound_trigger_uuid_t nUuid;
533 SoundTrigger::stringToGuid(nUuidString, &nUuid);
534 env->ReleaseStringUTFChars(jUuidString, nUuidString);
535 env->DeleteLocalRef(jUuidString);
536
Eric Laurentd3b82232014-07-30 08:57:39 -0700537 sound_trigger_uuid_t nVendorUuid;
538 jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.vendorUuid);
539 if (jUuid != NULL) {
540 jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
541 nUuidString = env->GetStringUTFChars(jUuidString, NULL);
542 SoundTrigger::stringToGuid(nUuidString, &nVendorUuid);
543 env->ReleaseStringUTFChars(jUuidString, nUuidString);
544 env->DeleteLocalRef(jUuidString);
545 } else {
546 SoundTrigger::stringToGuid("00000000-0000-0000-0000-000000000000", &nVendorUuid);
547 }
548
Eric Laurent60b62bc2014-04-18 17:50:49 -0700549 jData = (jbyteArray)env->GetObjectField(jSoundModel, gSoundModelFields.data);
550 if (jData == NULL) {
551 status = SOUNDTRIGGER_STATUS_BAD_VALUE;
552 goto exit;
553 }
554 size = env->GetArrayLength(jData);
555
Eric Laurent013f66b2014-07-06 16:35:00 -0700556 nData = env->GetByteArrayElements(jData, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700557 if (jData == NULL) {
558 status = SOUNDTRIGGER_STATUS_ERROR;
559 goto exit;
560 }
561
562 memoryDealer = new MemoryDealer(offset + size, "SoundTrigge-JNI::LoadModel");
563 if (memoryDealer == 0) {
564 status = SOUNDTRIGGER_STATUS_ERROR;
565 goto exit;
566 }
567 memory = memoryDealer->allocate(offset + size);
568 if (memory == 0 || memory->pointer() == NULL) {
569 status = SOUNDTRIGGER_STATUS_ERROR;
570 goto exit;
571 }
572
573 nSoundModel = (struct sound_trigger_sound_model *)memory->pointer();
574
575 nSoundModel->type = type;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700576 nSoundModel->uuid = nUuid;
Eric Laurentd3b82232014-07-30 08:57:39 -0700577 nSoundModel->vendor_uuid = nVendorUuid;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700578 nSoundModel->data_size = size;
579 nSoundModel->data_offset = offset;
580 memcpy((char *)nSoundModel + offset, nData, size);
581 if (type == SOUND_MODEL_TYPE_KEYPHRASE) {
582 struct sound_trigger_phrase_sound_model *phraseModel =
583 (struct sound_trigger_phrase_sound_model *)nSoundModel;
584
585 jobjectArray jPhrases =
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700586 (jobjectArray)env->GetObjectField(jSoundModel, gKeyphraseSoundModelFields.keyphrases);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700587 if (jPhrases == NULL) {
588 status = SOUNDTRIGGER_STATUS_BAD_VALUE;
589 goto exit;
590 }
591
592 size_t numPhrases = env->GetArrayLength(jPhrases);
593 phraseModel->num_phrases = numPhrases;
Eric Laurentd3b82232014-07-30 08:57:39 -0700594 ALOGV("loadSoundModel numPhrases %zu", numPhrases);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700595 for (size_t i = 0; i < numPhrases; i++) {
596 jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700597 phraseModel->phrases[i].id =
598 env->GetIntField(jPhrase,gKeyphraseFields.id);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700599 phraseModel->phrases[i].recognition_mode =
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700600 env->GetIntField(jPhrase,gKeyphraseFields.recognitionModes);
Eric Laurent013f66b2014-07-06 16:35:00 -0700601
602 jintArray jUsers = (jintArray)env->GetObjectField(jPhrase, gKeyphraseFields.users);
603 phraseModel->phrases[i].num_users = env->GetArrayLength(jUsers);
604 jint *nUsers = env->GetIntArrayElements(jUsers, NULL);
605 memcpy(phraseModel->phrases[i].users,
606 nUsers,
607 phraseModel->phrases[i].num_users * sizeof(int));
608 env->ReleaseIntArrayElements(jUsers, nUsers, 0);
609 env->DeleteLocalRef(jUsers);
610
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700611 jstring jLocale = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.locale);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700612 const char *nLocale = env->GetStringUTFChars(jLocale, NULL);
613 strncpy(phraseModel->phrases[i].locale,
614 nLocale,
615 SOUND_TRIGGER_MAX_LOCALE_LEN);
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700616 jstring jText = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.text);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700617 const char *nText = env->GetStringUTFChars(jText, NULL);
618 strncpy(phraseModel->phrases[i].text,
619 nText,
620 SOUND_TRIGGER_MAX_STRING_LEN);
621
622 env->ReleaseStringUTFChars(jLocale, nLocale);
623 env->DeleteLocalRef(jLocale);
624 env->ReleaseStringUTFChars(jText, nText);
625 env->DeleteLocalRef(jText);
Eric Laurentd3b82232014-07-30 08:57:39 -0700626 ALOGV("loadSoundModel phrases %zu text %s locale %s",
Eric Laurent60b62bc2014-04-18 17:50:49 -0700627 i, phraseModel->phrases[i].text, phraseModel->phrases[i].locale);
Eric Laurent013f66b2014-07-06 16:35:00 -0700628 env->DeleteLocalRef(jPhrase);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700629 }
630 env->DeleteLocalRef(jPhrases);
631 }
632 status = module->loadSoundModel(memory, &handle);
633 ALOGV("loadSoundModel status %d handle %d", status, handle);
634
635exit:
636 if (nHandle != NULL) {
637 nHandle[0] = (jint)handle;
638 env->ReleaseIntArrayElements(jHandle, nHandle, NULL);
639 }
640 if (nData != NULL) {
Eric Laurent013f66b2014-07-06 16:35:00 -0700641 env->ReleaseByteArrayElements(jData, nData, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700642 }
643 return status;
644}
645
646static jint
647android_hardware_SoundTrigger_unloadSoundModel(JNIEnv *env, jobject thiz,
648 jint jHandle)
649{
650 jint status = SOUNDTRIGGER_STATUS_OK;
651 ALOGV("unloadSoundModel");
652 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
653 if (module == NULL) {
654 return SOUNDTRIGGER_STATUS_ERROR;
655 }
656 status = module->unloadSoundModel((sound_model_handle_t)jHandle);
657
658 return status;
659}
660
661static jint
662android_hardware_SoundTrigger_startRecognition(JNIEnv *env, jobject thiz,
Eric Laurent013f66b2014-07-06 16:35:00 -0700663 jint jHandle, jobject jConfig)
Eric Laurent60b62bc2014-04-18 17:50:49 -0700664{
665 jint status = SOUNDTRIGGER_STATUS_OK;
666 ALOGV("startRecognition");
667 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
668 if (module == NULL) {
669 return SOUNDTRIGGER_STATUS_ERROR;
670 }
Eric Laurent013f66b2014-07-06 16:35:00 -0700671
672 if (!env->IsInstanceOf(jConfig, gRecognitionConfigClass)) {
673 return SOUNDTRIGGER_STATUS_BAD_VALUE;
674 }
675
676 jbyteArray jData = (jbyteArray)env->GetObjectField(jConfig, gRecognitionConfigFields.data);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700677 jsize dataSize = 0;
Eric Laurent013f66b2014-07-06 16:35:00 -0700678 jbyte *nData = NULL;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700679 if (jData != NULL) {
680 dataSize = env->GetArrayLength(jData);
681 if (dataSize == 0) {
682 return SOUNDTRIGGER_STATUS_BAD_VALUE;
683 }
Eric Laurent013f66b2014-07-06 16:35:00 -0700684 nData = env->GetByteArrayElements(jData, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700685 if (nData == NULL) {
686 return SOUNDTRIGGER_STATUS_ERROR;
687 }
Eric Laurent60b62bc2014-04-18 17:50:49 -0700688 }
689
Eric Laurent013f66b2014-07-06 16:35:00 -0700690 size_t totalSize = sizeof(struct sound_trigger_recognition_config) + dataSize;
691 sp<MemoryDealer> memoryDealer =
692 new MemoryDealer(totalSize, "SoundTrigge-JNI::StartRecognition");
693 if (memoryDealer == 0) {
694 return SOUNDTRIGGER_STATUS_ERROR;
695 }
696 sp<IMemory> memory = memoryDealer->allocate(totalSize);
697 if (memory == 0 || memory->pointer() == NULL) {
698 return SOUNDTRIGGER_STATUS_ERROR;
699 }
700 if (dataSize != 0) {
701 memcpy((char *)memory->pointer() + sizeof(struct sound_trigger_recognition_config),
702 nData,
703 dataSize);
704 env->ReleaseByteArrayElements(jData, nData, 0);
705 }
706 env->DeleteLocalRef(jData);
707 struct sound_trigger_recognition_config *config =
708 (struct sound_trigger_recognition_config *)memory->pointer();
709 config->data_size = dataSize;
710 config->data_offset = sizeof(struct sound_trigger_recognition_config);
711 config->capture_requested = env->GetIntField(jConfig,
712 gRecognitionConfigFields.captureRequested);
713
714 config->num_phrases = 0;
715 jobjectArray jPhrases =
716 (jobjectArray)env->GetObjectField(jConfig, gRecognitionConfigFields.keyphrases);
717 if (jPhrases != NULL) {
718 config->num_phrases = env->GetArrayLength(jPhrases);
719 }
720 ALOGV("startRecognition num phrases %d", config->num_phrases);
721 for (size_t i = 0; i < config->num_phrases; i++) {
722 jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
723 config->phrases[i].id = env->GetIntField(jPhrase,
724 gKeyphraseRecognitionExtraFields.id);
725 config->phrases[i].recognition_modes = env->GetIntField(jPhrase,
726 gKeyphraseRecognitionExtraFields.recognitionModes);
Eric Laurentd3b82232014-07-30 08:57:39 -0700727 config->phrases[i].confidence_level = env->GetIntField(jPhrase,
728 gKeyphraseRecognitionExtraFields.coarseConfidenceLevel);
Eric Laurent013f66b2014-07-06 16:35:00 -0700729 config->phrases[i].num_levels = 0;
730 jobjectArray jConfidenceLevels = (jobjectArray)env->GetObjectField(jPhrase,
731 gKeyphraseRecognitionExtraFields.confidenceLevels);
732 if (jConfidenceLevels != NULL) {
733 config->phrases[i].num_levels = env->GetArrayLength(jConfidenceLevels);
734 }
Eric Laurentd3b82232014-07-30 08:57:39 -0700735 ALOGV("startRecognition phrase %zu num_levels %d", i, config->phrases[i].num_levels);
Eric Laurent013f66b2014-07-06 16:35:00 -0700736 for (size_t j = 0; j < config->phrases[i].num_levels; j++) {
737 jobject jConfidenceLevel = env->GetObjectArrayElement(jConfidenceLevels, j);
738 config->phrases[i].levels[j].user_id = env->GetIntField(jConfidenceLevel,
739 gConfidenceLevelFields.userId);
740 config->phrases[i].levels[j].level = env->GetIntField(jConfidenceLevel,
741 gConfidenceLevelFields.confidenceLevel);
742 env->DeleteLocalRef(jConfidenceLevel);
743 }
Eric Laurentd3b82232014-07-30 08:57:39 -0700744 ALOGV("startRecognition phrases %zu", i);
Eric Laurent013f66b2014-07-06 16:35:00 -0700745 env->DeleteLocalRef(jConfidenceLevels);
746 env->DeleteLocalRef(jPhrase);
747 }
748 env->DeleteLocalRef(jPhrases);
749
Eric Laurent60b62bc2014-04-18 17:50:49 -0700750 status = module->startRecognition(jHandle, memory);
751 return status;
752}
753
754static jint
755android_hardware_SoundTrigger_stopRecognition(JNIEnv *env, jobject thiz,
756 jint jHandle)
757{
758 jint status = SOUNDTRIGGER_STATUS_OK;
759 ALOGV("stopRecognition");
760 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
761 if (module == NULL) {
762 return SOUNDTRIGGER_STATUS_ERROR;
763 }
764 status = module->stopRecognition(jHandle);
765 return status;
766}
767
768static JNINativeMethod gMethods[] = {
769 {"listModules",
770 "(Ljava/util/ArrayList;)I",
771 (void *)android_hardware_SoundTrigger_listModules},
772};
773
774
775static JNINativeMethod gModuleMethods[] = {
776 {"native_setup",
777 "(Ljava/lang/Object;)V",
778 (void *)android_hardware_SoundTrigger_setup},
779 {"native_finalize",
780 "()V",
781 (void *)android_hardware_SoundTrigger_finalize},
782 {"detach",
783 "()V",
784 (void *)android_hardware_SoundTrigger_detach},
785 {"loadSoundModel",
786 "(Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;[I)I",
787 (void *)android_hardware_SoundTrigger_loadSoundModel},
788 {"unloadSoundModel",
789 "(I)I",
790 (void *)android_hardware_SoundTrigger_unloadSoundModel},
791 {"startRecognition",
Eric Laurent013f66b2014-07-06 16:35:00 -0700792 "(ILandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;)I",
Eric Laurent60b62bc2014-04-18 17:50:49 -0700793 (void *)android_hardware_SoundTrigger_startRecognition},
794 {"stopRecognition",
795 "(I)I",
796 (void *)android_hardware_SoundTrigger_stopRecognition},
797};
798
799int register_android_hardware_SoundTrigger(JNIEnv *env)
800{
801 jclass arrayListClass = env->FindClass("java/util/ArrayList");
802 gArrayListClass = (jclass) env->NewGlobalRef(arrayListClass);
803 gArrayListMethods.add = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
804
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700805 jclass uuidClass = env->FindClass("java/util/UUID");
806 gUUIDClass = (jclass) env->NewGlobalRef(uuidClass);
807 gUUIDMethods.toString = env->GetMethodID(uuidClass, "toString", "()Ljava/lang/String;");
808
Eric Laurent60b62bc2014-04-18 17:50:49 -0700809 jclass lClass = env->FindClass(kSoundTriggerClassPathName);
810 gSoundTriggerClass = (jclass) env->NewGlobalRef(lClass);
811
812 jclass moduleClass = env->FindClass(kModuleClassPathName);
813 gModuleClass = (jclass) env->NewGlobalRef(moduleClass);
814 gPostEventFromNative = env->GetStaticMethodID(moduleClass, "postEventFromNative",
815 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
816 gModuleFields.mNativeContext = env->GetFieldID(moduleClass, "mNativeContext", "J");
817 gModuleFields.mId = env->GetFieldID(moduleClass, "mId", "I");
818
819
820 jclass modulePropertiesClass = env->FindClass(kModulePropertiesClassPathName);
821 gModulePropertiesClass = (jclass) env->NewGlobalRef(modulePropertiesClass);
822 gModulePropertiesCstor = env->GetMethodID(modulePropertiesClass, "<init>",
Eric Laurentd3b82232014-07-30 08:57:39 -0700823 "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700824
825 jclass soundModelClass = env->FindClass(kSoundModelClassPathName);
826 gSoundModelClass = (jclass) env->NewGlobalRef(soundModelClass);
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700827 gSoundModelFields.uuid = env->GetFieldID(soundModelClass, "uuid", "Ljava/util/UUID;");
Eric Laurentd3b82232014-07-30 08:57:39 -0700828 gSoundModelFields.vendorUuid = env->GetFieldID(soundModelClass, "vendorUuid", "Ljava/util/UUID;");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700829 gSoundModelFields.data = env->GetFieldID(soundModelClass, "data", "[B");
830
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700831 jclass keyphraseClass = env->FindClass(kKeyphraseClassPathName);
832 gKeyphraseClass = (jclass) env->NewGlobalRef(keyphraseClass);
833 gKeyphraseFields.id = env->GetFieldID(keyphraseClass, "id", "I");
834 gKeyphraseFields.recognitionModes = env->GetFieldID(keyphraseClass, "recognitionModes", "I");
835 gKeyphraseFields.locale = env->GetFieldID(keyphraseClass, "locale", "Ljava/lang/String;");
836 gKeyphraseFields.text = env->GetFieldID(keyphraseClass, "text", "Ljava/lang/String;");
Eric Laurent013f66b2014-07-06 16:35:00 -0700837 gKeyphraseFields.users = env->GetFieldID(keyphraseClass, "users", "[I");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700838
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700839 jclass keyphraseSoundModelClass = env->FindClass(kKeyphraseSoundModelClassPathName);
840 gKeyphraseSoundModelClass = (jclass) env->NewGlobalRef(keyphraseSoundModelClass);
841 gKeyphraseSoundModelFields.keyphrases = env->GetFieldID(keyphraseSoundModelClass,
842 "keyphrases",
843 "[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700844
845
846 jclass recognitionEventClass = env->FindClass(kRecognitionEventClassPathName);
847 gRecognitionEventClass = (jclass) env->NewGlobalRef(recognitionEventClass);
848 gRecognitionEventCstor = env->GetMethodID(recognitionEventClass, "<init>",
Eric Laurentd3b82232014-07-30 08:57:39 -0700849 "(IIZIIIZLandroid/media/AudioFormat;[B)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700850
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700851 jclass keyphraseRecognitionEventClass = env->FindClass(kKeyphraseRecognitionEventClassPathName);
852 gKeyphraseRecognitionEventClass = (jclass) env->NewGlobalRef(keyphraseRecognitionEventClass);
853 gKeyphraseRecognitionEventCstor = env->GetMethodID(keyphraseRecognitionEventClass, "<init>",
Eric Laurentd3b82232014-07-30 08:57:39 -0700854 "(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700855
856
Eric Laurent013f66b2014-07-06 16:35:00 -0700857 jclass keyRecognitionConfigClass = env->FindClass(kRecognitionConfigClassPathName);
858 gRecognitionConfigClass = (jclass) env->NewGlobalRef(keyRecognitionConfigClass);
859 gRecognitionConfigFields.captureRequested = env->GetFieldID(keyRecognitionConfigClass,
860 "captureRequested",
861 "Z");
862 gRecognitionConfigFields.keyphrases = env->GetFieldID(keyRecognitionConfigClass,
863 "keyphrases",
864 "[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;");
865 gRecognitionConfigFields.data = env->GetFieldID(keyRecognitionConfigClass,
866 "data",
867 "[B");
868
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700869 jclass keyphraseRecognitionExtraClass = env->FindClass(kKeyphraseRecognitionExtraClassPathName);
870 gKeyphraseRecognitionExtraClass = (jclass) env->NewGlobalRef(keyphraseRecognitionExtraClass);
871 gKeyphraseRecognitionExtraCstor = env->GetMethodID(keyphraseRecognitionExtraClass, "<init>",
Eric Laurentd3b82232014-07-30 08:57:39 -0700872 "(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V");
Eric Laurent013f66b2014-07-06 16:35:00 -0700873 gKeyphraseRecognitionExtraFields.id = env->GetFieldID(gKeyphraseRecognitionExtraClass, "id", "I");
Eric Laurentd3b82232014-07-30 08:57:39 -0700874 gKeyphraseRecognitionExtraFields.recognitionModes = env->GetFieldID(gKeyphraseRecognitionExtraClass,
875 "recognitionModes", "I");
876 gKeyphraseRecognitionExtraFields.coarseConfidenceLevel = env->GetFieldID(gKeyphraseRecognitionExtraClass,
877 "coarseConfidenceLevel", "I");
Eric Laurent013f66b2014-07-06 16:35:00 -0700878 gKeyphraseRecognitionExtraFields.confidenceLevels = env->GetFieldID(gKeyphraseRecognitionExtraClass,
879 "confidenceLevels",
880 "[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;");
881
882 jclass confidenceLevelClass = env->FindClass(kConfidenceLevelClassPathName);
883 gConfidenceLevelClass = (jclass) env->NewGlobalRef(confidenceLevelClass);
884 gConfidenceLevelCstor = env->GetMethodID(confidenceLevelClass, "<init>", "(II)V");
885 gConfidenceLevelFields.userId = env->GetFieldID(confidenceLevelClass, "userId", "I");
886 gConfidenceLevelFields.confidenceLevel = env->GetFieldID(confidenceLevelClass,
887 "confidenceLevel", "I");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700888
Eric Laurentd3b82232014-07-30 08:57:39 -0700889 jclass audioFormatClass = env->FindClass(kAudioFormatClassPathName);
890 gAudioFormatClass = (jclass) env->NewGlobalRef(audioFormatClass);
891 gAudioFormatCstor = env->GetMethodID(audioFormatClass, "<init>", "(III)V");
892
893 jclass soundModelEventClass = env->FindClass(kSoundModelEventClassPathName);
894 gSoundModelEventClass = (jclass) env->NewGlobalRef(soundModelEventClass);
895 gSoundModelEventCstor = env->GetMethodID(soundModelEventClass, "<init>",
896 "(II[B)V");
897
898
Eric Laurent60b62bc2014-04-18 17:50:49 -0700899 int status = AndroidRuntime::registerNativeMethods(env,
900 kSoundTriggerClassPathName, gMethods, NELEM(gMethods));
901
902 if (status == 0) {
903 status = AndroidRuntime::registerNativeMethods(env,
904 kModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));
905 }
906
Eric Laurent013f66b2014-07-06 16:35:00 -0700907
Eric Laurent60b62bc2014-04-18 17:50:49 -0700908 return status;
909}