blob: c7805ea12f02541cf318c1a9389f26ee829655e8 [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"
Steven Moreland2279b252017-07-19 09:50:45 -070023#include <nativehelper/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
Ryan Bavettaee3fc892016-01-26 20:49:28 -080071static const char* const kGenericSoundModelClassPathName =
72 "android/hardware/soundtrigger/SoundTrigger$GenericSoundModel";
73static jclass gGenericSoundModelClass;
74
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070075static const char* const kKeyphraseClassPathName =
76 "android/hardware/soundtrigger/SoundTrigger$Keyphrase";
77static jclass gKeyphraseClass;
Eric Laurent60b62bc2014-04-18 17:50:49 -070078static struct {
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070079 jfieldID id;
Eric Laurent60b62bc2014-04-18 17:50:49 -070080 jfieldID recognitionModes;
81 jfieldID locale;
82 jfieldID text;
Eric Laurent013f66b2014-07-06 16:35:00 -070083 jfieldID users;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070084} gKeyphraseFields;
Eric Laurent60b62bc2014-04-18 17:50:49 -070085
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070086static const char* const kKeyphraseSoundModelClassPathName =
87 "android/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel";
88static jclass gKeyphraseSoundModelClass;
Eric Laurent60b62bc2014-04-18 17:50:49 -070089static struct {
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070090 jfieldID keyphrases;
91} gKeyphraseSoundModelFields;
Eric Laurent60b62bc2014-04-18 17:50:49 -070092
Eric Laurent013f66b2014-07-06 16:35:00 -070093static const char* const kRecognitionConfigClassPathName =
94 "android/hardware/soundtrigger/SoundTrigger$RecognitionConfig";
95static jclass gRecognitionConfigClass;
96static struct {
97 jfieldID captureRequested;
98 jfieldID keyphrases;
99 jfieldID data;
100} gRecognitionConfigFields;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700101
102static const char* const kRecognitionEventClassPathName =
103 "android/hardware/soundtrigger/SoundTrigger$RecognitionEvent";
104static jclass gRecognitionEventClass;
105static jmethodID gRecognitionEventCstor;
106
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700107static const char* const kKeyphraseRecognitionEventClassPathName =
108 "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent";
109static jclass gKeyphraseRecognitionEventClass;
110static jmethodID gKeyphraseRecognitionEventCstor;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700111
Ryan Bavettaee3fc892016-01-26 20:49:28 -0800112static const char* const kGenericRecognitionEventClassPathName =
113 "android/hardware/soundtrigger/SoundTrigger$GenericRecognitionEvent";
114static jclass gGenericRecognitionEventClass;
115static jmethodID gGenericRecognitionEventCstor;
116
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700117static const char* const kKeyphraseRecognitionExtraClassPathName =
118 "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra";
119static jclass gKeyphraseRecognitionExtraClass;
120static jmethodID gKeyphraseRecognitionExtraCstor;
Eric Laurent013f66b2014-07-06 16:35:00 -0700121static struct {
122 jfieldID id;
123 jfieldID recognitionModes;
Eric Laurentd3b82232014-07-30 08:57:39 -0700124 jfieldID coarseConfidenceLevel;
Eric Laurent013f66b2014-07-06 16:35:00 -0700125 jfieldID confidenceLevels;
126} gKeyphraseRecognitionExtraFields;
127
128static const char* const kConfidenceLevelClassPathName =
129 "android/hardware/soundtrigger/SoundTrigger$ConfidenceLevel";
130static jclass gConfidenceLevelClass;
131static jmethodID gConfidenceLevelCstor;
132static struct {
133 jfieldID userId;
134 jfieldID confidenceLevel;
135} gConfidenceLevelFields;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700136
Eric Laurentd3b82232014-07-30 08:57:39 -0700137static const char* const kAudioFormatClassPathName =
138 "android/media/AudioFormat";
139static jclass gAudioFormatClass;
140static jmethodID gAudioFormatCstor;
141
142static const char* const kSoundModelEventClassPathName =
143 "android/hardware/soundtrigger/SoundTrigger$SoundModelEvent";
144static jclass gSoundModelEventClass;
145static jmethodID gSoundModelEventCstor;
146
Eric Laurent60b62bc2014-04-18 17:50:49 -0700147static Mutex gLock;
148
149enum {
150 SOUNDTRIGGER_STATUS_OK = 0,
151 SOUNDTRIGGER_STATUS_ERROR = INT_MIN,
152 SOUNDTRIGGER_PERMISSION_DENIED = -1,
153 SOUNDTRIGGER_STATUS_NO_INIT = -19,
154 SOUNDTRIGGER_STATUS_BAD_VALUE = -22,
155 SOUNDTRIGGER_STATUS_DEAD_OBJECT = -32,
156 SOUNDTRIGGER_INVALID_OPERATION = -38,
157};
158
159enum {
160 SOUNDTRIGGER_EVENT_RECOGNITION = 1,
161 SOUNDTRIGGER_EVENT_SERVICE_DIED = 2,
Eric Laurentd3b82232014-07-30 08:57:39 -0700162 SOUNDTRIGGER_EVENT_SOUNDMODEL = 3,
163 SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE = 4,
Eric Laurent60b62bc2014-04-18 17:50:49 -0700164};
165
166// ----------------------------------------------------------------------------
167// ref-counted object for callbacks
168class JNISoundTriggerCallback: public SoundTriggerCallback
169{
170public:
171 JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
172 ~JNISoundTriggerCallback();
173
174 virtual void onRecognitionEvent(struct sound_trigger_recognition_event *event);
Eric Laurentd3b82232014-07-30 08:57:39 -0700175 virtual void onSoundModelEvent(struct sound_trigger_model_event *event);
176 virtual void onServiceStateChange(sound_trigger_service_state_t state);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700177 virtual void onServiceDied();
178
179private:
180 jclass mClass; // Reference to SoundTrigger class
181 jobject mObject; // Weak ref to SoundTrigger Java object to call on
182};
183
184JNISoundTriggerCallback::JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
185{
186
187 // Hold onto the SoundTriggerModule class for use in calling the static method
188 // that posts events to the application thread.
189 jclass clazz = env->GetObjectClass(thiz);
190 if (clazz == NULL) {
191 ALOGE("Can't find class %s", kModuleClassPathName);
192 return;
193 }
194 mClass = (jclass)env->NewGlobalRef(clazz);
195
196 // We use a weak reference so the SoundTriggerModule object can be garbage collected.
197 // The reference is only used as a proxy for callbacks.
198 mObject = env->NewGlobalRef(weak_thiz);
199}
200
201JNISoundTriggerCallback::~JNISoundTriggerCallback()
202{
203 // remove global references
204 JNIEnv *env = AndroidRuntime::getJNIEnv();
205 env->DeleteGlobalRef(mObject);
206 env->DeleteGlobalRef(mClass);
207}
208
209void JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognition_event *event)
210{
211 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurentd3b82232014-07-30 08:57:39 -0700212 jobject jEvent = NULL;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700213 jbyteArray jData = NULL;
Eric Laurentd3b82232014-07-30 08:57:39 -0700214
Eric Laurent60b62bc2014-04-18 17:50:49 -0700215 if (event->data_size) {
216 jData = env->NewByteArray(event->data_size);
217 jbyte *nData = env->GetByteArrayElements(jData, NULL);
218 memcpy(nData, (char *)event + event->data_offset, event->data_size);
219 env->ReleaseByteArrayElements(jData, nData, 0);
220 }
221
Eric Laurentd3b82232014-07-30 08:57:39 -0700222 jobject jAudioFormat = NULL;
Eric Laurent39fcca02014-09-05 16:44:19 -0700223 if (event->trigger_in_data || event->capture_available) {
Eric Laurent66ef06a2019-02-26 18:23:22 -0800224 jint channelMask = (jint)audio_channel_mask_get_bits(event->audio_config.channel_mask);
225 jint channelIndexMask = (jint)AUDIO_CHANNEL_NONE;
226
227 switch (audio_channel_mask_get_representation(event->audio_config.channel_mask)) {
228 case AUDIO_CHANNEL_REPRESENTATION_INDEX:
229 channelIndexMask = channelMask;
230 channelMask = (jint)AUDIO_CHANNEL_NONE;
231 break;
232 default:
233 break;
234 }
Eric Laurentd3b82232014-07-30 08:57:39 -0700235 jAudioFormat = env->NewObject(gAudioFormatClass,
236 gAudioFormatCstor,
237 audioFormatFromNative(event->audio_config.format),
238 event->audio_config.sample_rate,
Eric Laurent66ef06a2019-02-26 18:23:22 -0800239 channelMask,
240 channelIndexMask);
Eric Laurentd3b82232014-07-30 08:57:39 -0700241
242 }
Eric Laurent60b62bc2014-04-18 17:50:49 -0700243 if (event->type == SOUND_MODEL_TYPE_KEYPHRASE) {
244 struct sound_trigger_phrase_recognition_event *phraseEvent =
245 (struct sound_trigger_phrase_recognition_event *)event;
246
247 jobjectArray jExtras = env->NewObjectArray(phraseEvent->num_phrases,
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700248 gKeyphraseRecognitionExtraClass, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700249 if (jExtras == NULL) {
250 return;
251 }
252
253 for (size_t i = 0; i < phraseEvent->num_phrases; i++) {
Eric Laurent013f66b2014-07-06 16:35:00 -0700254 jobjectArray jConfidenceLevels = env->NewObjectArray(
255 phraseEvent->phrase_extras[i].num_levels,
256 gConfidenceLevelClass, NULL);
257
Eric Laurent60b62bc2014-04-18 17:50:49 -0700258 if (jConfidenceLevels == NULL) {
259 return;
260 }
Eric Laurent013f66b2014-07-06 16:35:00 -0700261 for (size_t j = 0; j < phraseEvent->phrase_extras[i].num_levels; j++) {
262 jobject jConfidenceLevel = env->NewObject(gConfidenceLevelClass,
263 gConfidenceLevelCstor,
264 phraseEvent->phrase_extras[i].levels[j].user_id,
265 phraseEvent->phrase_extras[i].levels[j].level);
266 env->SetObjectArrayElement(jConfidenceLevels, j, jConfidenceLevel);
267 env->DeleteLocalRef(jConfidenceLevel);
268 }
269
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700270 jobject jNewExtra = env->NewObject(gKeyphraseRecognitionExtraClass,
271 gKeyphraseRecognitionExtraCstor,
Eric Laurent013f66b2014-07-06 16:35:00 -0700272 phraseEvent->phrase_extras[i].id,
273 phraseEvent->phrase_extras[i].recognition_modes,
Eric Laurentd3b82232014-07-30 08:57:39 -0700274 phraseEvent->phrase_extras[i].confidence_level,
Eric Laurent013f66b2014-07-06 16:35:00 -0700275 jConfidenceLevels);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700276
277 if (jNewExtra == NULL) {
278 return;
279 }
280 env->SetObjectArrayElement(jExtras, i, jNewExtra);
Eric Laurent013f66b2014-07-06 16:35:00 -0700281 env->DeleteLocalRef(jNewExtra);
282 env->DeleteLocalRef(jConfidenceLevels);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700283 }
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700284 jEvent = env->NewObject(gKeyphraseRecognitionEventClass, gKeyphraseRecognitionEventCstor,
Eric Laurent60b62bc2014-04-18 17:50:49 -0700285 event->status, event->model, event->capture_available,
Eric Laurentd3b82232014-07-30 08:57:39 -0700286 event->capture_session, event->capture_delay_ms,
287 event->capture_preamble_ms, event->trigger_in_data,
288 jAudioFormat, jData, jExtras);
Eric Laurent8f89feb2014-10-29 15:52:43 -0700289 env->DeleteLocalRef(jExtras);
Ryan Bavettaee3fc892016-01-26 20:49:28 -0800290 } else if (event->type == SOUND_MODEL_TYPE_GENERIC) {
291 jEvent = env->NewObject(gGenericRecognitionEventClass, gGenericRecognitionEventCstor,
292 event->status, event->model, event->capture_available,
293 event->capture_session, event->capture_delay_ms,
294 event->capture_preamble_ms, event->trigger_in_data,
295 jAudioFormat, jData);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700296 } else {
297 jEvent = env->NewObject(gRecognitionEventClass, gRecognitionEventCstor,
298 event->status, event->model, event->capture_available,
Eric Laurent013f66b2014-07-06 16:35:00 -0700299 event->capture_session, event->capture_delay_ms,
Eric Laurentd3b82232014-07-30 08:57:39 -0700300 event->capture_preamble_ms, event->trigger_in_data,
301 jAudioFormat, jData);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700302 }
303
Eric Laurent8f89feb2014-10-29 15:52:43 -0700304 if (jAudioFormat != NULL) {
305 env->DeleteLocalRef(jAudioFormat);
306 }
307 if (jData != NULL) {
308 env->DeleteLocalRef(jData);
309 }
Eric Laurent60b62bc2014-04-18 17:50:49 -0700310
311 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
312 SOUNDTRIGGER_EVENT_RECOGNITION, 0, 0, jEvent);
Eric Laurentd3b82232014-07-30 08:57:39 -0700313
314 env->DeleteLocalRef(jEvent);
315 if (env->ExceptionCheck()) {
316 ALOGW("An exception occurred while notifying an event.");
317 env->ExceptionClear();
318 }
319}
320
321void JNISoundTriggerCallback::onSoundModelEvent(struct sound_trigger_model_event *event)
322{
323 JNIEnv *env = AndroidRuntime::getJNIEnv();
324 jobject jEvent = NULL;
325 jbyteArray jData = NULL;
326
327 if (event->data_size) {
328 jData = env->NewByteArray(event->data_size);
329 jbyte *nData = env->GetByteArrayElements(jData, NULL);
330 memcpy(nData, (char *)event + event->data_offset, event->data_size);
331 env->ReleaseByteArrayElements(jData, nData, 0);
332 }
333
334 jEvent = env->NewObject(gSoundModelEventClass, gSoundModelEventCstor,
335 event->status, event->model, jData);
336
337 env->DeleteLocalRef(jData);
338 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
339 SOUNDTRIGGER_EVENT_SOUNDMODEL, 0, 0, jEvent);
340 env->DeleteLocalRef(jEvent);
341 if (env->ExceptionCheck()) {
342 ALOGW("An exception occurred while notifying an event.");
343 env->ExceptionClear();
344 }
345}
346
347void JNISoundTriggerCallback::onServiceStateChange(sound_trigger_service_state_t state)
348{
349 JNIEnv *env = AndroidRuntime::getJNIEnv();
350 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
351 SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE, state, 0, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700352 if (env->ExceptionCheck()) {
353 ALOGW("An exception occurred while notifying an event.");
354 env->ExceptionClear();
355 }
356}
357
358void JNISoundTriggerCallback::onServiceDied()
359{
360 JNIEnv *env = AndroidRuntime::getJNIEnv();
361
362 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
363 SOUNDTRIGGER_EVENT_SERVICE_DIED, 0, 0, NULL);
364 if (env->ExceptionCheck()) {
365 ALOGW("An exception occurred while notifying an event.");
366 env->ExceptionClear();
367 }
368}
369
370// ----------------------------------------------------------------------------
371
372static sp<SoundTrigger> getSoundTrigger(JNIEnv* env, jobject thiz)
373{
374 Mutex::Autolock l(gLock);
375 SoundTrigger* const st = (SoundTrigger*)env->GetLongField(thiz,
376 gModuleFields.mNativeContext);
377 return sp<SoundTrigger>(st);
378}
379
380static sp<SoundTrigger> setSoundTrigger(JNIEnv* env, jobject thiz, const sp<SoundTrigger>& module)
381{
382 Mutex::Autolock l(gLock);
383 sp<SoundTrigger> old = (SoundTrigger*)env->GetLongField(thiz,
384 gModuleFields.mNativeContext);
385 if (module.get()) {
386 module->incStrong((void*)setSoundTrigger);
387 }
388 if (old != 0) {
389 old->decStrong((void*)setSoundTrigger);
390 }
391 env->SetLongField(thiz, gModuleFields.mNativeContext, (jlong)module.get());
392 return old;
393}
394
395
396static jint
397android_hardware_SoundTrigger_listModules(JNIEnv *env, jobject clazz,
398 jobject jModules)
399{
400 ALOGV("listModules");
401
402 if (jModules == NULL) {
403 ALOGE("listModules NULL AudioPatch ArrayList");
404 return SOUNDTRIGGER_STATUS_BAD_VALUE;
405 }
406 if (!env->IsInstanceOf(jModules, gArrayListClass)) {
407 ALOGE("listModules not an arraylist");
408 return SOUNDTRIGGER_STATUS_BAD_VALUE;
409 }
410
411 unsigned int numModules = 0;
412 struct sound_trigger_module_descriptor *nModules = NULL;
413
414 status_t status = SoundTrigger::listModules(nModules, &numModules);
415 if (status != NO_ERROR || numModules == 0) {
416 return (jint)status;
417 }
418
419 nModules = (struct sound_trigger_module_descriptor *)
420 calloc(numModules, sizeof(struct sound_trigger_module_descriptor));
421
422 status = SoundTrigger::listModules(nModules, &numModules);
423 ALOGV("listModules SoundTrigger::listModules status %d numModules %d", status, numModules);
424
425 if (status != NO_ERROR) {
426 numModules = 0;
427 }
428
429 for (size_t i = 0; i < numModules; i++) {
430 char str[SOUND_TRIGGER_MAX_STRING_LEN];
431
432 jstring implementor = env->NewStringUTF(nModules[i].properties.implementor);
433 jstring description = env->NewStringUTF(nModules[i].properties.description);
434 SoundTrigger::guidToString(&nModules[i].properties.uuid,
435 str,
436 SOUND_TRIGGER_MAX_STRING_LEN);
437 jstring uuid = env->NewStringUTF(str);
438
Eric Laurentd3b82232014-07-30 08:57:39 -0700439 ALOGV("listModules module %zu id %d description %s maxSoundModels %d",
Eric Laurent60b62bc2014-04-18 17:50:49 -0700440 i, nModules[i].handle, nModules[i].properties.description,
441 nModules[i].properties.max_sound_models);
442
443 jobject newModuleDesc = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
444 nModules[i].handle,
445 implementor, description, uuid,
446 nModules[i].properties.version,
447 nModules[i].properties.max_sound_models,
448 nModules[i].properties.max_key_phrases,
449 nModules[i].properties.max_users,
450 nModules[i].properties.recognition_modes,
451 nModules[i].properties.capture_transition,
452 nModules[i].properties.max_buffer_ms,
453 nModules[i].properties.concurrent_capture,
Eric Laurentd3b82232014-07-30 08:57:39 -0700454 nModules[i].properties.power_consumption_mw,
455 nModules[i].properties.trigger_in_event);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700456
457 env->DeleteLocalRef(implementor);
458 env->DeleteLocalRef(description);
459 env->DeleteLocalRef(uuid);
460 if (newModuleDesc == NULL) {
461 status = SOUNDTRIGGER_STATUS_ERROR;
462 goto exit;
463 }
464 env->CallBooleanMethod(jModules, gArrayListMethods.add, newModuleDesc);
465 }
466
467exit:
468 free(nModules);
469 return (jint) status;
470}
471
472static void
473android_hardware_SoundTrigger_setup(JNIEnv *env, jobject thiz, jobject weak_this)
474{
475 ALOGV("setup");
476
477 sp<JNISoundTriggerCallback> callback = new JNISoundTriggerCallback(env, thiz, weak_this);
478
479 sound_trigger_module_handle_t handle =
480 (sound_trigger_module_handle_t)env->GetIntField(thiz, gModuleFields.mId);
481
482 sp<SoundTrigger> module = SoundTrigger::attach(handle, callback);
483 if (module == 0) {
484 return;
485 }
486
487 setSoundTrigger(env, thiz, module);
488}
489
490static void
491android_hardware_SoundTrigger_detach(JNIEnv *env, jobject thiz)
492{
493 ALOGV("detach");
494 sp<SoundTrigger> module = setSoundTrigger(env, thiz, 0);
495 ALOGV("detach module %p", module.get());
496 if (module != 0) {
497 ALOGV("detach module->detach()");
498 module->detach();
499 }
500}
501
502static void
503android_hardware_SoundTrigger_finalize(JNIEnv *env, jobject thiz)
504{
505 ALOGV("finalize");
506 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
507 if (module != 0) {
508 ALOGW("SoundTrigger finalized without being detached");
509 }
510 android_hardware_SoundTrigger_detach(env, thiz);
511}
512
513static jint
514android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
515 jobject jSoundModel, jintArray jHandle)
516{
517 jint status = SOUNDTRIGGER_STATUS_OK;
Eric Laurent013f66b2014-07-06 16:35:00 -0700518 jbyte *nData = NULL;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700519 struct sound_trigger_sound_model *nSoundModel;
520 jbyteArray jData;
521 sp<MemoryDealer> memoryDealer;
522 sp<IMemory> memory;
523 size_t size;
George Burgess IV2df0c672017-01-24 15:48:28 -0800524 sound_model_handle_t handle = 0;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700525 jobject jUuid;
526 jstring jUuidString;
527 const char *nUuidString;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700528
529 ALOGV("loadSoundModel");
530 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
531 if (module == NULL) {
532 return SOUNDTRIGGER_STATUS_ERROR;
533 }
534 if (jHandle == NULL) {
535 return SOUNDTRIGGER_STATUS_BAD_VALUE;
536 }
537 jsize jHandleLen = env->GetArrayLength(jHandle);
538 if (jHandleLen == 0) {
539 return SOUNDTRIGGER_STATUS_BAD_VALUE;
540 }
541 jint *nHandle = env->GetIntArrayElements(jHandle, NULL);
542 if (nHandle == NULL) {
543 return SOUNDTRIGGER_STATUS_ERROR;
544 }
545 if (!env->IsInstanceOf(jSoundModel, gSoundModelClass)) {
546 status = SOUNDTRIGGER_STATUS_BAD_VALUE;
547 goto exit;
548 }
549 size_t offset;
550 sound_trigger_sound_model_type_t type;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700551 if (env->IsInstanceOf(jSoundModel, gKeyphraseSoundModelClass)) {
Eric Laurent60b62bc2014-04-18 17:50:49 -0700552 offset = sizeof(struct sound_trigger_phrase_sound_model);
553 type = SOUND_MODEL_TYPE_KEYPHRASE;
Ryan Bavettaee3fc892016-01-26 20:49:28 -0800554 } else if (env->IsInstanceOf(jSoundModel, gGenericSoundModelClass)) {
555 offset = sizeof(struct sound_trigger_generic_sound_model);
556 type = SOUND_MODEL_TYPE_GENERIC;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700557 } else {
558 offset = sizeof(struct sound_trigger_sound_model);
559 type = SOUND_MODEL_TYPE_UNKNOWN;
560 }
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700561
562 jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.uuid);
563 jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
564 nUuidString = env->GetStringUTFChars(jUuidString, NULL);
565 sound_trigger_uuid_t nUuid;
566 SoundTrigger::stringToGuid(nUuidString, &nUuid);
567 env->ReleaseStringUTFChars(jUuidString, nUuidString);
568 env->DeleteLocalRef(jUuidString);
569
Eric Laurentd3b82232014-07-30 08:57:39 -0700570 sound_trigger_uuid_t nVendorUuid;
571 jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.vendorUuid);
572 if (jUuid != NULL) {
573 jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
574 nUuidString = env->GetStringUTFChars(jUuidString, NULL);
575 SoundTrigger::stringToGuid(nUuidString, &nVendorUuid);
576 env->ReleaseStringUTFChars(jUuidString, nUuidString);
577 env->DeleteLocalRef(jUuidString);
578 } else {
579 SoundTrigger::stringToGuid("00000000-0000-0000-0000-000000000000", &nVendorUuid);
580 }
581
Eric Laurent60b62bc2014-04-18 17:50:49 -0700582 jData = (jbyteArray)env->GetObjectField(jSoundModel, gSoundModelFields.data);
583 if (jData == NULL) {
584 status = SOUNDTRIGGER_STATUS_BAD_VALUE;
585 goto exit;
586 }
587 size = env->GetArrayLength(jData);
588
Eric Laurent013f66b2014-07-06 16:35:00 -0700589 nData = env->GetByteArrayElements(jData, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700590 if (jData == NULL) {
591 status = SOUNDTRIGGER_STATUS_ERROR;
592 goto exit;
593 }
594
595 memoryDealer = new MemoryDealer(offset + size, "SoundTrigge-JNI::LoadModel");
596 if (memoryDealer == 0) {
597 status = SOUNDTRIGGER_STATUS_ERROR;
598 goto exit;
599 }
600 memory = memoryDealer->allocate(offset + size);
601 if (memory == 0 || memory->pointer() == NULL) {
602 status = SOUNDTRIGGER_STATUS_ERROR;
603 goto exit;
604 }
605
606 nSoundModel = (struct sound_trigger_sound_model *)memory->pointer();
607
608 nSoundModel->type = type;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700609 nSoundModel->uuid = nUuid;
Eric Laurentd3b82232014-07-30 08:57:39 -0700610 nSoundModel->vendor_uuid = nVendorUuid;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700611 nSoundModel->data_size = size;
612 nSoundModel->data_offset = offset;
613 memcpy((char *)nSoundModel + offset, nData, size);
614 if (type == SOUND_MODEL_TYPE_KEYPHRASE) {
615 struct sound_trigger_phrase_sound_model *phraseModel =
616 (struct sound_trigger_phrase_sound_model *)nSoundModel;
617
618 jobjectArray jPhrases =
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700619 (jobjectArray)env->GetObjectField(jSoundModel, gKeyphraseSoundModelFields.keyphrases);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700620 if (jPhrases == NULL) {
621 status = SOUNDTRIGGER_STATUS_BAD_VALUE;
622 goto exit;
623 }
624
625 size_t numPhrases = env->GetArrayLength(jPhrases);
626 phraseModel->num_phrases = numPhrases;
Eric Laurentd3b82232014-07-30 08:57:39 -0700627 ALOGV("loadSoundModel numPhrases %zu", numPhrases);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700628 for (size_t i = 0; i < numPhrases; i++) {
629 jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700630 phraseModel->phrases[i].id =
631 env->GetIntField(jPhrase,gKeyphraseFields.id);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700632 phraseModel->phrases[i].recognition_mode =
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700633 env->GetIntField(jPhrase,gKeyphraseFields.recognitionModes);
Eric Laurent013f66b2014-07-06 16:35:00 -0700634
635 jintArray jUsers = (jintArray)env->GetObjectField(jPhrase, gKeyphraseFields.users);
636 phraseModel->phrases[i].num_users = env->GetArrayLength(jUsers);
637 jint *nUsers = env->GetIntArrayElements(jUsers, NULL);
638 memcpy(phraseModel->phrases[i].users,
639 nUsers,
640 phraseModel->phrases[i].num_users * sizeof(int));
641 env->ReleaseIntArrayElements(jUsers, nUsers, 0);
642 env->DeleteLocalRef(jUsers);
643
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700644 jstring jLocale = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.locale);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700645 const char *nLocale = env->GetStringUTFChars(jLocale, NULL);
646 strncpy(phraseModel->phrases[i].locale,
647 nLocale,
648 SOUND_TRIGGER_MAX_LOCALE_LEN);
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700649 jstring jText = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.text);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700650 const char *nText = env->GetStringUTFChars(jText, NULL);
651 strncpy(phraseModel->phrases[i].text,
652 nText,
653 SOUND_TRIGGER_MAX_STRING_LEN);
654
655 env->ReleaseStringUTFChars(jLocale, nLocale);
656 env->DeleteLocalRef(jLocale);
657 env->ReleaseStringUTFChars(jText, nText);
658 env->DeleteLocalRef(jText);
Eric Laurentd3b82232014-07-30 08:57:39 -0700659 ALOGV("loadSoundModel phrases %zu text %s locale %s",
Eric Laurent60b62bc2014-04-18 17:50:49 -0700660 i, phraseModel->phrases[i].text, phraseModel->phrases[i].locale);
Eric Laurent013f66b2014-07-06 16:35:00 -0700661 env->DeleteLocalRef(jPhrase);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700662 }
663 env->DeleteLocalRef(jPhrases);
Ryan Bavettaee3fc892016-01-26 20:49:28 -0800664 } else if (type == SOUND_MODEL_TYPE_GENERIC) {
665 /* No initialization needed */
Eric Laurent60b62bc2014-04-18 17:50:49 -0700666 }
667 status = module->loadSoundModel(memory, &handle);
668 ALOGV("loadSoundModel status %d handle %d", status, handle);
669
670exit:
671 if (nHandle != NULL) {
672 nHandle[0] = (jint)handle;
673 env->ReleaseIntArrayElements(jHandle, nHandle, NULL);
674 }
675 if (nData != NULL) {
Eric Laurent013f66b2014-07-06 16:35:00 -0700676 env->ReleaseByteArrayElements(jData, nData, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700677 }
678 return status;
679}
680
681static jint
682android_hardware_SoundTrigger_unloadSoundModel(JNIEnv *env, jobject thiz,
683 jint jHandle)
684{
685 jint status = SOUNDTRIGGER_STATUS_OK;
686 ALOGV("unloadSoundModel");
687 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
688 if (module == NULL) {
689 return SOUNDTRIGGER_STATUS_ERROR;
690 }
691 status = module->unloadSoundModel((sound_model_handle_t)jHandle);
692
693 return status;
694}
695
696static jint
697android_hardware_SoundTrigger_startRecognition(JNIEnv *env, jobject thiz,
Eric Laurent013f66b2014-07-06 16:35:00 -0700698 jint jHandle, jobject jConfig)
Eric Laurent60b62bc2014-04-18 17:50:49 -0700699{
700 jint status = SOUNDTRIGGER_STATUS_OK;
701 ALOGV("startRecognition");
702 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
703 if (module == NULL) {
704 return SOUNDTRIGGER_STATUS_ERROR;
705 }
Eric Laurent013f66b2014-07-06 16:35:00 -0700706
707 if (!env->IsInstanceOf(jConfig, gRecognitionConfigClass)) {
708 return SOUNDTRIGGER_STATUS_BAD_VALUE;
709 }
710
711 jbyteArray jData = (jbyteArray)env->GetObjectField(jConfig, gRecognitionConfigFields.data);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700712 jsize dataSize = 0;
Eric Laurent013f66b2014-07-06 16:35:00 -0700713 jbyte *nData = NULL;
Eric Laurent60b62bc2014-04-18 17:50:49 -0700714 if (jData != NULL) {
715 dataSize = env->GetArrayLength(jData);
716 if (dataSize == 0) {
717 return SOUNDTRIGGER_STATUS_BAD_VALUE;
718 }
Eric Laurent013f66b2014-07-06 16:35:00 -0700719 nData = env->GetByteArrayElements(jData, NULL);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700720 if (nData == NULL) {
721 return SOUNDTRIGGER_STATUS_ERROR;
722 }
Eric Laurent60b62bc2014-04-18 17:50:49 -0700723 }
724
Eric Laurent013f66b2014-07-06 16:35:00 -0700725 size_t totalSize = sizeof(struct sound_trigger_recognition_config) + dataSize;
726 sp<MemoryDealer> memoryDealer =
727 new MemoryDealer(totalSize, "SoundTrigge-JNI::StartRecognition");
728 if (memoryDealer == 0) {
729 return SOUNDTRIGGER_STATUS_ERROR;
730 }
731 sp<IMemory> memory = memoryDealer->allocate(totalSize);
732 if (memory == 0 || memory->pointer() == NULL) {
733 return SOUNDTRIGGER_STATUS_ERROR;
734 }
735 if (dataSize != 0) {
736 memcpy((char *)memory->pointer() + sizeof(struct sound_trigger_recognition_config),
737 nData,
738 dataSize);
739 env->ReleaseByteArrayElements(jData, nData, 0);
740 }
741 env->DeleteLocalRef(jData);
742 struct sound_trigger_recognition_config *config =
743 (struct sound_trigger_recognition_config *)memory->pointer();
744 config->data_size = dataSize;
745 config->data_offset = sizeof(struct sound_trigger_recognition_config);
Eric Laurent89311c22015-05-22 10:30:13 -0700746 config->capture_requested = env->GetBooleanField(jConfig,
Eric Laurent013f66b2014-07-06 16:35:00 -0700747 gRecognitionConfigFields.captureRequested);
748
749 config->num_phrases = 0;
750 jobjectArray jPhrases =
751 (jobjectArray)env->GetObjectField(jConfig, gRecognitionConfigFields.keyphrases);
752 if (jPhrases != NULL) {
753 config->num_phrases = env->GetArrayLength(jPhrases);
754 }
755 ALOGV("startRecognition num phrases %d", config->num_phrases);
756 for (size_t i = 0; i < config->num_phrases; i++) {
757 jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
758 config->phrases[i].id = env->GetIntField(jPhrase,
759 gKeyphraseRecognitionExtraFields.id);
760 config->phrases[i].recognition_modes = env->GetIntField(jPhrase,
761 gKeyphraseRecognitionExtraFields.recognitionModes);
Eric Laurentd3b82232014-07-30 08:57:39 -0700762 config->phrases[i].confidence_level = env->GetIntField(jPhrase,
763 gKeyphraseRecognitionExtraFields.coarseConfidenceLevel);
Eric Laurent013f66b2014-07-06 16:35:00 -0700764 config->phrases[i].num_levels = 0;
765 jobjectArray jConfidenceLevels = (jobjectArray)env->GetObjectField(jPhrase,
766 gKeyphraseRecognitionExtraFields.confidenceLevels);
767 if (jConfidenceLevels != NULL) {
768 config->phrases[i].num_levels = env->GetArrayLength(jConfidenceLevels);
769 }
Eric Laurentd3b82232014-07-30 08:57:39 -0700770 ALOGV("startRecognition phrase %zu num_levels %d", i, config->phrases[i].num_levels);
Eric Laurent013f66b2014-07-06 16:35:00 -0700771 for (size_t j = 0; j < config->phrases[i].num_levels; j++) {
772 jobject jConfidenceLevel = env->GetObjectArrayElement(jConfidenceLevels, j);
773 config->phrases[i].levels[j].user_id = env->GetIntField(jConfidenceLevel,
774 gConfidenceLevelFields.userId);
775 config->phrases[i].levels[j].level = env->GetIntField(jConfidenceLevel,
776 gConfidenceLevelFields.confidenceLevel);
777 env->DeleteLocalRef(jConfidenceLevel);
778 }
Eric Laurentd3b82232014-07-30 08:57:39 -0700779 ALOGV("startRecognition phrases %zu", i);
Eric Laurent013f66b2014-07-06 16:35:00 -0700780 env->DeleteLocalRef(jConfidenceLevels);
781 env->DeleteLocalRef(jPhrase);
782 }
783 env->DeleteLocalRef(jPhrases);
784
Eric Laurent60b62bc2014-04-18 17:50:49 -0700785 status = module->startRecognition(jHandle, memory);
786 return status;
787}
788
789static jint
790android_hardware_SoundTrigger_stopRecognition(JNIEnv *env, jobject thiz,
791 jint jHandle)
792{
793 jint status = SOUNDTRIGGER_STATUS_OK;
794 ALOGV("stopRecognition");
795 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
796 if (module == NULL) {
797 return SOUNDTRIGGER_STATUS_ERROR;
798 }
799 status = module->stopRecognition(jHandle);
800 return status;
801}
802
mike dooleyb2ab04a2018-11-07 15:48:54 +0100803static jint
Michael Dooley291751e2018-10-16 19:53:29 +0000804android_hardware_SoundTrigger_getModelState(JNIEnv *env, jobject thiz,
805 jint jHandle)
806{
mike dooleyb2ab04a2018-11-07 15:48:54 +0100807 jint status = SOUNDTRIGGER_STATUS_OK;
Michael Dooley291751e2018-10-16 19:53:29 +0000808 ALOGV("getModelState");
809 sp<SoundTrigger> module = getSoundTrigger(env, thiz);
810 if (module == NULL) {
mike dooleyb2ab04a2018-11-07 15:48:54 +0100811 return SOUNDTRIGGER_STATUS_ERROR;
Michael Dooley291751e2018-10-16 19:53:29 +0000812 }
mike dooleyb2ab04a2018-11-07 15:48:54 +0100813 status = module->getModelState(jHandle);
814 return status;
Michael Dooley291751e2018-10-16 19:53:29 +0000815}
816
Daniel Micay76f6a862015-09-19 17:31:01 -0400817static const JNINativeMethod gMethods[] = {
Eric Laurent60b62bc2014-04-18 17:50:49 -0700818 {"listModules",
819 "(Ljava/util/ArrayList;)I",
820 (void *)android_hardware_SoundTrigger_listModules},
821};
822
823
Daniel Micay76f6a862015-09-19 17:31:01 -0400824static const JNINativeMethod gModuleMethods[] = {
Eric Laurent60b62bc2014-04-18 17:50:49 -0700825 {"native_setup",
826 "(Ljava/lang/Object;)V",
827 (void *)android_hardware_SoundTrigger_setup},
828 {"native_finalize",
829 "()V",
830 (void *)android_hardware_SoundTrigger_finalize},
831 {"detach",
832 "()V",
833 (void *)android_hardware_SoundTrigger_detach},
834 {"loadSoundModel",
835 "(Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;[I)I",
836 (void *)android_hardware_SoundTrigger_loadSoundModel},
837 {"unloadSoundModel",
838 "(I)I",
839 (void *)android_hardware_SoundTrigger_unloadSoundModel},
840 {"startRecognition",
Eric Laurent013f66b2014-07-06 16:35:00 -0700841 "(ILandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;)I",
Eric Laurent60b62bc2014-04-18 17:50:49 -0700842 (void *)android_hardware_SoundTrigger_startRecognition},
843 {"stopRecognition",
844 "(I)I",
845 (void *)android_hardware_SoundTrigger_stopRecognition},
Michael Dooley291751e2018-10-16 19:53:29 +0000846 {"getModelState",
mike dooleyb2ab04a2018-11-07 15:48:54 +0100847 "(I)I",
Michael Dooley291751e2018-10-16 19:53:29 +0000848 (void *)android_hardware_SoundTrigger_getModelState},
Eric Laurent60b62bc2014-04-18 17:50:49 -0700849};
850
851int register_android_hardware_SoundTrigger(JNIEnv *env)
852{
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800853 jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
854 gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
855 gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700856
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800857 jclass uuidClass = FindClassOrDie(env, "java/util/UUID");
858 gUUIDClass = MakeGlobalRefOrDie(env, uuidClass);
859 gUUIDMethods.toString = GetMethodIDOrDie(env, uuidClass, "toString", "()Ljava/lang/String;");
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700860
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800861 jclass lClass = FindClassOrDie(env, kSoundTriggerClassPathName);
862 gSoundTriggerClass = MakeGlobalRefOrDie(env, lClass);
Eric Laurent60b62bc2014-04-18 17:50:49 -0700863
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800864 jclass moduleClass = FindClassOrDie(env, kModuleClassPathName);
865 gModuleClass = MakeGlobalRefOrDie(env, moduleClass);
866 gPostEventFromNative = GetStaticMethodIDOrDie(env, moduleClass, "postEventFromNative",
867 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
868 gModuleFields.mNativeContext = GetFieldIDOrDie(env, moduleClass, "mNativeContext", "J");
869 gModuleFields.mId = GetFieldIDOrDie(env, moduleClass, "mId", "I");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700870
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800871 jclass modulePropertiesClass = FindClassOrDie(env, kModulePropertiesClassPathName);
872 gModulePropertiesClass = MakeGlobalRefOrDie(env, modulePropertiesClass);
873 gModulePropertiesCstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>",
874 "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700875
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800876 jclass soundModelClass = FindClassOrDie(env, kSoundModelClassPathName);
877 gSoundModelClass = MakeGlobalRefOrDie(env, soundModelClass);
878 gSoundModelFields.uuid = GetFieldIDOrDie(env, soundModelClass, "uuid", "Ljava/util/UUID;");
879 gSoundModelFields.vendorUuid = GetFieldIDOrDie(env, soundModelClass, "vendorUuid",
880 "Ljava/util/UUID;");
881 gSoundModelFields.data = GetFieldIDOrDie(env, soundModelClass, "data", "[B");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700882
Ryan Bavettaee3fc892016-01-26 20:49:28 -0800883 jclass genericSoundModelClass = FindClassOrDie(env, kGenericSoundModelClassPathName);
884 gGenericSoundModelClass = MakeGlobalRefOrDie(env, genericSoundModelClass);
885
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800886 jclass keyphraseClass = FindClassOrDie(env, kKeyphraseClassPathName);
887 gKeyphraseClass = MakeGlobalRefOrDie(env, keyphraseClass);
888 gKeyphraseFields.id = GetFieldIDOrDie(env, keyphraseClass, "id", "I");
889 gKeyphraseFields.recognitionModes = GetFieldIDOrDie(env, keyphraseClass, "recognitionModes",
890 "I");
891 gKeyphraseFields.locale = GetFieldIDOrDie(env, keyphraseClass, "locale", "Ljava/lang/String;");
892 gKeyphraseFields.text = GetFieldIDOrDie(env, keyphraseClass, "text", "Ljava/lang/String;");
893 gKeyphraseFields.users = GetFieldIDOrDie(env, keyphraseClass, "users", "[I");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700894
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800895 jclass keyphraseSoundModelClass = FindClassOrDie(env, kKeyphraseSoundModelClassPathName);
896 gKeyphraseSoundModelClass = MakeGlobalRefOrDie(env, keyphraseSoundModelClass);
897 gKeyphraseSoundModelFields.keyphrases = GetFieldIDOrDie(env, keyphraseSoundModelClass,
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700898 "keyphrases",
899 "[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700900
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800901 jclass recognitionEventClass = FindClassOrDie(env, kRecognitionEventClassPathName);
902 gRecognitionEventClass = MakeGlobalRefOrDie(env, recognitionEventClass);
903 gRecognitionEventCstor = GetMethodIDOrDie(env, recognitionEventClass, "<init>",
Eric Laurentd3b82232014-07-30 08:57:39 -0700904 "(IIZIIIZLandroid/media/AudioFormat;[B)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700905
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800906 jclass keyphraseRecognitionEventClass = FindClassOrDie(env,
907 kKeyphraseRecognitionEventClassPathName);
908 gKeyphraseRecognitionEventClass = MakeGlobalRefOrDie(env, keyphraseRecognitionEventClass);
909 gKeyphraseRecognitionEventCstor = GetMethodIDOrDie(env, keyphraseRecognitionEventClass, "<init>",
Eric Laurentd3b82232014-07-30 08:57:39 -0700910 "(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700911
Ryan Bavettaee3fc892016-01-26 20:49:28 -0800912 jclass genericRecognitionEventClass = FindClassOrDie(env,
913 kGenericRecognitionEventClassPathName);
914 gGenericRecognitionEventClass = MakeGlobalRefOrDie(env, genericRecognitionEventClass);
915 gGenericRecognitionEventCstor = GetMethodIDOrDie(env, genericRecognitionEventClass, "<init>",
916 "(IIZIIIZLandroid/media/AudioFormat;[B)V");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700917
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800918 jclass keyRecognitionConfigClass = FindClassOrDie(env, kRecognitionConfigClassPathName);
919 gRecognitionConfigClass = MakeGlobalRefOrDie(env, keyRecognitionConfigClass);
920 gRecognitionConfigFields.captureRequested = GetFieldIDOrDie(env, keyRecognitionConfigClass,
921 "captureRequested", "Z");
922 gRecognitionConfigFields.keyphrases = GetFieldIDOrDie(env, keyRecognitionConfigClass,
923 "keyphrases", "[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;");
924 gRecognitionConfigFields.data = GetFieldIDOrDie(env, keyRecognitionConfigClass, "data", "[B");
Eric Laurent013f66b2014-07-06 16:35:00 -0700925
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800926 jclass keyphraseRecognitionExtraClass = FindClassOrDie(env,
927 kKeyphraseRecognitionExtraClassPathName);
928 gKeyphraseRecognitionExtraClass = MakeGlobalRefOrDie(env, keyphraseRecognitionExtraClass);
929 gKeyphraseRecognitionExtraCstor = GetMethodIDOrDie(env, keyphraseRecognitionExtraClass,
930 "<init>", "(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V");
931 gKeyphraseRecognitionExtraFields.id = GetFieldIDOrDie(env, gKeyphraseRecognitionExtraClass,
932 "id", "I");
933 gKeyphraseRecognitionExtraFields.recognitionModes = GetFieldIDOrDie(env,
934 gKeyphraseRecognitionExtraClass, "recognitionModes", "I");
935 gKeyphraseRecognitionExtraFields.coarseConfidenceLevel = GetFieldIDOrDie(env,
936 gKeyphraseRecognitionExtraClass, "coarseConfidenceLevel", "I");
937 gKeyphraseRecognitionExtraFields.confidenceLevels = GetFieldIDOrDie(env,
938 gKeyphraseRecognitionExtraClass, "confidenceLevels",
939 "[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;");
Eric Laurent013f66b2014-07-06 16:35:00 -0700940
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800941 jclass confidenceLevelClass = FindClassOrDie(env, kConfidenceLevelClassPathName);
942 gConfidenceLevelClass = MakeGlobalRefOrDie(env, confidenceLevelClass);
943 gConfidenceLevelCstor = GetMethodIDOrDie(env, confidenceLevelClass, "<init>", "(II)V");
944 gConfidenceLevelFields.userId = GetFieldIDOrDie(env, confidenceLevelClass, "userId", "I");
945 gConfidenceLevelFields.confidenceLevel = GetFieldIDOrDie(env, confidenceLevelClass,
Eric Laurent013f66b2014-07-06 16:35:00 -0700946 "confidenceLevel", "I");
Eric Laurent60b62bc2014-04-18 17:50:49 -0700947
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800948 jclass audioFormatClass = FindClassOrDie(env, kAudioFormatClassPathName);
949 gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
Andy Hunga9470c12015-01-29 17:16:03 -0800950 gAudioFormatCstor = GetMethodIDOrDie(env, audioFormatClass, "<init>", "(IIII)V");
Eric Laurentd3b82232014-07-30 08:57:39 -0700951
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800952 jclass soundModelEventClass = FindClassOrDie(env, kSoundModelEventClassPathName);
953 gSoundModelEventClass = MakeGlobalRefOrDie(env, soundModelEventClass);
954 gSoundModelEventCstor = GetMethodIDOrDie(env, soundModelEventClass, "<init>", "(II[B)V");
Eric Laurentd3b82232014-07-30 08:57:39 -0700955
956
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800957 RegisterMethodsOrDie(env, kSoundTriggerClassPathName, gMethods, NELEM(gMethods));
958 return RegisterMethodsOrDie(env, kModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));
Eric Laurent60b62bc2014-04-18 17:50:49 -0700959}