android_hardware_SoundTrigger.cpp revision 2df0c67152cbf24ced14a963bb935484f424b167
160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent/* 260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** 360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** Copyright 2014, The Android Open Source Project 460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** 560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** Licensed under the Apache License, Version 2.0 (the "License"); 660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** you may not use this file except in compliance with the License. 760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** You may obtain a copy of the License at 860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** 960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** http://www.apache.org/licenses/LICENSE-2.0 1060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** 1160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** Unless required by applicable law or agreed to in writing, software 1260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** distributed under the License is distributed on an "AS IS" BASIS, 1360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** See the License for the specific language governing permissions and 1560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent** limitations under the License. 1660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent*/ 1760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 1860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent//#define LOG_NDEBUG 0 1960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#define LOG_TAG "SoundTrigger-JNI" 2060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <utils/Log.h> 2160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 2260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include "jni.h" 2360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include "JNIHelp.h" 24ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h" 2560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <system/sound_trigger.h> 2660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <soundtrigger/SoundTriggerCallback.h> 2760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <soundtrigger/SoundTrigger.h> 2860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <utils/RefBase.h> 2960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <utils/Vector.h> 3060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <binder/IMemory.h> 3160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent#include <binder/MemoryDealer.h> 32d3b8223377b8046280e4c09e728edc600171f941Eric Laurent#include "android_media_AudioFormat.h" 3360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 3460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentusing namespace android; 3560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 3660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gArrayListClass; 3760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct { 3860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jmethodID add; 3960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} gArrayListMethods; 4060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 41d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gUUIDClass; 42d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic struct { 43d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jmethodID toString; 44d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha} gUUIDMethods; 45d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha 4660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kSoundTriggerClassPathName = "android/hardware/soundtrigger/SoundTrigger"; 4760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gSoundTriggerClass; 4860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 4960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kModuleClassPathName = "android/hardware/soundtrigger/SoundTriggerModule"; 5060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gModuleClass; 5160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct { 5260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jfieldID mNativeContext; 5360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jfieldID mId; 5460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} gModuleFields; 5560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jmethodID gPostEventFromNative; 5660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 5760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kModulePropertiesClassPathName = 5860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "android/hardware/soundtrigger/SoundTrigger$ModuleProperties"; 5960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gModulePropertiesClass; 6060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jmethodID gModulePropertiesCstor; 6160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 6260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kSoundModelClassPathName = 6360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "android/hardware/soundtrigger/SoundTrigger$SoundModel"; 6460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gSoundModelClass; 6560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct { 66d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jfieldID uuid; 67d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jfieldID vendorUuid; 6860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jfieldID data; 6960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} gSoundModelFields; 7060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 71ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavettastatic const char* const kGenericSoundModelClassPathName = 72ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta "android/hardware/soundtrigger/SoundTrigger$GenericSoundModel"; 73ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavettastatic jclass gGenericSoundModelClass; 74ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta 75d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic const char* const kKeyphraseClassPathName = 76d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha "android/hardware/soundtrigger/SoundTrigger$Keyphrase"; 77d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gKeyphraseClass; 7860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct { 79d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jfieldID id; 8060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jfieldID recognitionModes; 8160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jfieldID locale; 8260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jfieldID text; 83013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jfieldID users; 84d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha} gKeyphraseFields; 8560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 86d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic const char* const kKeyphraseSoundModelClassPathName = 87d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha "android/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel"; 88d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gKeyphraseSoundModelClass; 8960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic struct { 90d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jfieldID keyphrases; 91d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha} gKeyphraseSoundModelFields; 9260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 93013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic const char* const kRecognitionConfigClassPathName = 94013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent "android/hardware/soundtrigger/SoundTrigger$RecognitionConfig"; 95013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic jclass gRecognitionConfigClass; 96013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic struct { 97013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jfieldID captureRequested; 98013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jfieldID keyphrases; 99013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jfieldID data; 100013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent} gRecognitionConfigFields; 10160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 10260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic const char* const kRecognitionEventClassPathName = 10360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "android/hardware/soundtrigger/SoundTrigger$RecognitionEvent"; 10460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jclass gRecognitionEventClass; 10560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jmethodID gRecognitionEventCstor; 10660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 107d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic const char* const kKeyphraseRecognitionEventClassPathName = 108d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent"; 109d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gKeyphraseRecognitionEventClass; 110d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jmethodID gKeyphraseRecognitionEventCstor; 11160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 112ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavettastatic const char* const kGenericRecognitionEventClassPathName = 113ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta "android/hardware/soundtrigger/SoundTrigger$GenericRecognitionEvent"; 114ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavettastatic jclass gGenericRecognitionEventClass; 115ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavettastatic jmethodID gGenericRecognitionEventCstor; 116ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta 117d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic const char* const kKeyphraseRecognitionExtraClassPathName = 118d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra"; 119d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jclass gKeyphraseRecognitionExtraClass; 120d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthastatic jmethodID gKeyphraseRecognitionExtraCstor; 121013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic struct { 122013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jfieldID id; 123013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jfieldID recognitionModes; 124d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jfieldID coarseConfidenceLevel; 125013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jfieldID confidenceLevels; 126013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent} gKeyphraseRecognitionExtraFields; 127013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 128013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic const char* const kConfidenceLevelClassPathName = 129013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent "android/hardware/soundtrigger/SoundTrigger$ConfidenceLevel"; 130013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic jclass gConfidenceLevelClass; 131013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic jmethodID gConfidenceLevelCstor; 132013f66b92db609fceeff9c8171daca13d057cc95Eric Laurentstatic struct { 133013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jfieldID userId; 134013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jfieldID confidenceLevel; 135013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent} gConfidenceLevelFields; 13660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 137d3b8223377b8046280e4c09e728edc600171f941Eric Laurentstatic const char* const kAudioFormatClassPathName = 138d3b8223377b8046280e4c09e728edc600171f941Eric Laurent "android/media/AudioFormat"; 139d3b8223377b8046280e4c09e728edc600171f941Eric Laurentstatic jclass gAudioFormatClass; 140d3b8223377b8046280e4c09e728edc600171f941Eric Laurentstatic jmethodID gAudioFormatCstor; 141d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 142d3b8223377b8046280e4c09e728edc600171f941Eric Laurentstatic const char* const kSoundModelEventClassPathName = 143d3b8223377b8046280e4c09e728edc600171f941Eric Laurent "android/hardware/soundtrigger/SoundTrigger$SoundModelEvent"; 144d3b8223377b8046280e4c09e728edc600171f941Eric Laurentstatic jclass gSoundModelEventClass; 145d3b8223377b8046280e4c09e728edc600171f941Eric Laurentstatic jmethodID gSoundModelEventCstor; 146d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 14760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic Mutex gLock; 14860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 14960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentenum { 15060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_STATUS_OK = 0, 15160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_STATUS_ERROR = INT_MIN, 15260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_PERMISSION_DENIED = -1, 15360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_STATUS_NO_INIT = -19, 15460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_STATUS_BAD_VALUE = -22, 15560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_STATUS_DEAD_OBJECT = -32, 15660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_INVALID_OPERATION = -38, 15760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}; 15860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 15960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentenum { 16060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_EVENT_RECOGNITION = 1, 16160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_EVENT_SERVICE_DIED = 2, 162d3b8223377b8046280e4c09e728edc600171f941Eric Laurent SOUNDTRIGGER_EVENT_SOUNDMODEL = 3, 163d3b8223377b8046280e4c09e728edc600171f941Eric Laurent SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE = 4, 16460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}; 16560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 16660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent// ---------------------------------------------------------------------------- 16760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent// ref-counted object for callbacks 16860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentclass JNISoundTriggerCallback: public SoundTriggerCallback 16960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 17060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentpublic: 17160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz); 17260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ~JNISoundTriggerCallback(); 17360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 17460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent virtual void onRecognitionEvent(struct sound_trigger_recognition_event *event); 175d3b8223377b8046280e4c09e728edc600171f941Eric Laurent virtual void onSoundModelEvent(struct sound_trigger_model_event *event); 176d3b8223377b8046280e4c09e728edc600171f941Eric Laurent virtual void onServiceStateChange(sound_trigger_service_state_t state); 17760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent virtual void onServiceDied(); 17860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 17960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentprivate: 18060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jclass mClass; // Reference to SoundTrigger class 18160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jobject mObject; // Weak ref to SoundTrigger Java object to call on 18260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}; 18360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 18460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric LaurentJNISoundTriggerCallback::JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz) 18560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 18660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 18760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent // Hold onto the SoundTriggerModule class for use in calling the static method 18860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent // that posts events to the application thread. 18960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jclass clazz = env->GetObjectClass(thiz); 19060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (clazz == NULL) { 19160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGE("Can't find class %s", kModuleClassPathName); 19260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return; 19360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 19460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent mClass = (jclass)env->NewGlobalRef(clazz); 19560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 19660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent // We use a weak reference so the SoundTriggerModule object can be garbage collected. 19760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent // The reference is only used as a proxy for callbacks. 19860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent mObject = env->NewGlobalRef(weak_thiz); 19960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 20060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 20160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric LaurentJNISoundTriggerCallback::~JNISoundTriggerCallback() 20260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 20360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent // remove global references 20460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent JNIEnv *env = AndroidRuntime::getJNIEnv(); 20560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->DeleteGlobalRef(mObject); 20660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->DeleteGlobalRef(mClass); 20760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 20860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 20960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentvoid JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognition_event *event) 21060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 21160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent JNIEnv *env = AndroidRuntime::getJNIEnv(); 212d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jobject jEvent = NULL; 21360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jbyteArray jData = NULL; 214d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 21560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (event->data_size) { 21660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jData = env->NewByteArray(event->data_size); 21760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jbyte *nData = env->GetByteArrayElements(jData, NULL); 21860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent memcpy(nData, (char *)event + event->data_offset, event->data_size); 21960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->ReleaseByteArrayElements(jData, nData, 0); 22060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 22160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 222d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jobject jAudioFormat = NULL; 22339fcca0a503658f91a14b4b1d35dfc4ac9fce9d9Eric Laurent if (event->trigger_in_data || event->capture_available) { 224d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jAudioFormat = env->NewObject(gAudioFormatClass, 225d3b8223377b8046280e4c09e728edc600171f941Eric Laurent gAudioFormatCstor, 226d3b8223377b8046280e4c09e728edc600171f941Eric Laurent audioFormatFromNative(event->audio_config.format), 227d3b8223377b8046280e4c09e728edc600171f941Eric Laurent event->audio_config.sample_rate, 228d3b8223377b8046280e4c09e728edc600171f941Eric Laurent inChannelMaskFromNative(event->audio_config.channel_mask)); 229d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 230d3b8223377b8046280e4c09e728edc600171f941Eric Laurent } 23160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (event->type == SOUND_MODEL_TYPE_KEYPHRASE) { 23260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent struct sound_trigger_phrase_recognition_event *phraseEvent = 23360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (struct sound_trigger_phrase_recognition_event *)event; 23460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 23560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jobjectArray jExtras = env->NewObjectArray(phraseEvent->num_phrases, 236d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha gKeyphraseRecognitionExtraClass, NULL); 23760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jExtras == NULL) { 23860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return; 23960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 24060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 24160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent for (size_t i = 0; i < phraseEvent->num_phrases; i++) { 242013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jobjectArray jConfidenceLevels = env->NewObjectArray( 243013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent phraseEvent->phrase_extras[i].num_levels, 244013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent gConfidenceLevelClass, NULL); 245013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 24660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jConfidenceLevels == NULL) { 24760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return; 24860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 249013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent for (size_t j = 0; j < phraseEvent->phrase_extras[i].num_levels; j++) { 250013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jobject jConfidenceLevel = env->NewObject(gConfidenceLevelClass, 251013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent gConfidenceLevelCstor, 252013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent phraseEvent->phrase_extras[i].levels[j].user_id, 253013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent phraseEvent->phrase_extras[i].levels[j].level); 254013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->SetObjectArrayElement(jConfidenceLevels, j, jConfidenceLevel); 255013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jConfidenceLevel); 256013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent } 257013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 258d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jobject jNewExtra = env->NewObject(gKeyphraseRecognitionExtraClass, 259d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha gKeyphraseRecognitionExtraCstor, 260013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent phraseEvent->phrase_extras[i].id, 261013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent phraseEvent->phrase_extras[i].recognition_modes, 262d3b8223377b8046280e4c09e728edc600171f941Eric Laurent phraseEvent->phrase_extras[i].confidence_level, 263013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jConfidenceLevels); 26460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 26560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jNewExtra == NULL) { 26660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return; 26760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 26860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->SetObjectArrayElement(jExtras, i, jNewExtra); 269013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jNewExtra); 270013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jConfidenceLevels); 27160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 272d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jEvent = env->NewObject(gKeyphraseRecognitionEventClass, gKeyphraseRecognitionEventCstor, 27360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent event->status, event->model, event->capture_available, 274d3b8223377b8046280e4c09e728edc600171f941Eric Laurent event->capture_session, event->capture_delay_ms, 275d3b8223377b8046280e4c09e728edc600171f941Eric Laurent event->capture_preamble_ms, event->trigger_in_data, 276d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jAudioFormat, jData, jExtras); 2778f89feba39be8e705c6b9f550c5af141a9e189daEric Laurent env->DeleteLocalRef(jExtras); 278ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta } else if (event->type == SOUND_MODEL_TYPE_GENERIC) { 279ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta jEvent = env->NewObject(gGenericRecognitionEventClass, gGenericRecognitionEventCstor, 280ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta event->status, event->model, event->capture_available, 281ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta event->capture_session, event->capture_delay_ms, 282ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta event->capture_preamble_ms, event->trigger_in_data, 283ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta jAudioFormat, jData); 28460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } else { 28560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jEvent = env->NewObject(gRecognitionEventClass, gRecognitionEventCstor, 28660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent event->status, event->model, event->capture_available, 287013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent event->capture_session, event->capture_delay_ms, 288d3b8223377b8046280e4c09e728edc600171f941Eric Laurent event->capture_preamble_ms, event->trigger_in_data, 289d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jAudioFormat, jData); 2908f89feba39be8e705c6b9f550c5af141a9e189daEric Laurent } 2918f89feba39be8e705c6b9f550c5af141a9e189daEric Laurent 2928f89feba39be8e705c6b9f550c5af141a9e189daEric Laurent if (jAudioFormat != NULL) { 293d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->DeleteLocalRef(jAudioFormat); 2948f89feba39be8e705c6b9f550c5af141a9e189daEric Laurent } 2958f89feba39be8e705c6b9f550c5af141a9e189daEric Laurent if (jData != NULL) { 296d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->DeleteLocalRef(jData); 29760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 29860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 29960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject, 30060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_EVENT_RECOGNITION, 0, 0, jEvent); 301d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 302d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->DeleteLocalRef(jEvent); 303d3b8223377b8046280e4c09e728edc600171f941Eric Laurent if (env->ExceptionCheck()) { 304d3b8223377b8046280e4c09e728edc600171f941Eric Laurent ALOGW("An exception occurred while notifying an event."); 305d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->ExceptionClear(); 306d3b8223377b8046280e4c09e728edc600171f941Eric Laurent } 307d3b8223377b8046280e4c09e728edc600171f941Eric Laurent} 308d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 309d3b8223377b8046280e4c09e728edc600171f941Eric Laurentvoid JNISoundTriggerCallback::onSoundModelEvent(struct sound_trigger_model_event *event) 310d3b8223377b8046280e4c09e728edc600171f941Eric Laurent{ 311d3b8223377b8046280e4c09e728edc600171f941Eric Laurent JNIEnv *env = AndroidRuntime::getJNIEnv(); 312d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jobject jEvent = NULL; 313d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jbyteArray jData = NULL; 314d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 315d3b8223377b8046280e4c09e728edc600171f941Eric Laurent if (event->data_size) { 316d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jData = env->NewByteArray(event->data_size); 317d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jbyte *nData = env->GetByteArrayElements(jData, NULL); 318d3b8223377b8046280e4c09e728edc600171f941Eric Laurent memcpy(nData, (char *)event + event->data_offset, event->data_size); 319d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->ReleaseByteArrayElements(jData, nData, 0); 320d3b8223377b8046280e4c09e728edc600171f941Eric Laurent } 321d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 322d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jEvent = env->NewObject(gSoundModelEventClass, gSoundModelEventCstor, 323d3b8223377b8046280e4c09e728edc600171f941Eric Laurent event->status, event->model, jData); 324d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 325d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->DeleteLocalRef(jData); 326d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject, 327d3b8223377b8046280e4c09e728edc600171f941Eric Laurent SOUNDTRIGGER_EVENT_SOUNDMODEL, 0, 0, jEvent); 328d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->DeleteLocalRef(jEvent); 329d3b8223377b8046280e4c09e728edc600171f941Eric Laurent if (env->ExceptionCheck()) { 330d3b8223377b8046280e4c09e728edc600171f941Eric Laurent ALOGW("An exception occurred while notifying an event."); 331d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->ExceptionClear(); 332d3b8223377b8046280e4c09e728edc600171f941Eric Laurent } 333d3b8223377b8046280e4c09e728edc600171f941Eric Laurent} 334d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 335d3b8223377b8046280e4c09e728edc600171f941Eric Laurentvoid JNISoundTriggerCallback::onServiceStateChange(sound_trigger_service_state_t state) 336d3b8223377b8046280e4c09e728edc600171f941Eric Laurent{ 337d3b8223377b8046280e4c09e728edc600171f941Eric Laurent JNIEnv *env = AndroidRuntime::getJNIEnv(); 338d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject, 339d3b8223377b8046280e4c09e728edc600171f941Eric Laurent SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE, state, 0, NULL); 34060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (env->ExceptionCheck()) { 34160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGW("An exception occurred while notifying an event."); 34260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->ExceptionClear(); 34360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 34460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 34560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 34660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentvoid JNISoundTriggerCallback::onServiceDied() 34760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 34860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent JNIEnv *env = AndroidRuntime::getJNIEnv(); 34960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 35060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject, 35160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUNDTRIGGER_EVENT_SERVICE_DIED, 0, 0, NULL); 35260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (env->ExceptionCheck()) { 35360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGW("An exception occurred while notifying an event."); 35460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->ExceptionClear(); 35560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 35660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 35760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 35860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent// ---------------------------------------------------------------------------- 35960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 36060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic sp<SoundTrigger> getSoundTrigger(JNIEnv* env, jobject thiz) 36160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 36260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent Mutex::Autolock l(gLock); 36360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SoundTrigger* const st = (SoundTrigger*)env->GetLongField(thiz, 36460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent gModuleFields.mNativeContext); 36560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return sp<SoundTrigger>(st); 36660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 36760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 36860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic sp<SoundTrigger> setSoundTrigger(JNIEnv* env, jobject thiz, const sp<SoundTrigger>& module) 36960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 37060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent Mutex::Autolock l(gLock); 37160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<SoundTrigger> old = (SoundTrigger*)env->GetLongField(thiz, 37260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent gModuleFields.mNativeContext); 37360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (module.get()) { 37460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent module->incStrong((void*)setSoundTrigger); 37560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 37660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (old != 0) { 37760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent old->decStrong((void*)setSoundTrigger); 37860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 37960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->SetLongField(thiz, gModuleFields.mNativeContext, (jlong)module.get()); 38060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return old; 38160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 38260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 38360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 38460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint 38560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_listModules(JNIEnv *env, jobject clazz, 38660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jobject jModules) 38760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 38860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("listModules"); 38960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 39060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jModules == NULL) { 39160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGE("listModules NULL AudioPatch ArrayList"); 39260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_BAD_VALUE; 39360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 39460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (!env->IsInstanceOf(jModules, gArrayListClass)) { 39560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGE("listModules not an arraylist"); 39660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_BAD_VALUE; 39760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 39860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 39960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent unsigned int numModules = 0; 40060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent struct sound_trigger_module_descriptor *nModules = NULL; 40160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 40260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status_t status = SoundTrigger::listModules(nModules, &numModules); 40360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (status != NO_ERROR || numModules == 0) { 40460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return (jint)status; 40560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 40660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 40760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules = (struct sound_trigger_module_descriptor *) 40860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent calloc(numModules, sizeof(struct sound_trigger_module_descriptor)); 40960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 41060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = SoundTrigger::listModules(nModules, &numModules); 41160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("listModules SoundTrigger::listModules status %d numModules %d", status, numModules); 41260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 41360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (status != NO_ERROR) { 41460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent numModules = 0; 41560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 41660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 41760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent for (size_t i = 0; i < numModules; i++) { 41860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent char str[SOUND_TRIGGER_MAX_STRING_LEN]; 41960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 42060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jstring implementor = env->NewStringUTF(nModules[i].properties.implementor); 42160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jstring description = env->NewStringUTF(nModules[i].properties.description); 42260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SoundTrigger::guidToString(&nModules[i].properties.uuid, 42360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent str, 42460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUND_TRIGGER_MAX_STRING_LEN); 42560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jstring uuid = env->NewStringUTF(str); 42660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 427d3b8223377b8046280e4c09e728edc600171f941Eric Laurent ALOGV("listModules module %zu id %d description %s maxSoundModels %d", 42860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent i, nModules[i].handle, nModules[i].properties.description, 42960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].properties.max_sound_models); 43060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 43160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jobject newModuleDesc = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor, 43260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].handle, 43360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent implementor, description, uuid, 43460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].properties.version, 43560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].properties.max_sound_models, 43660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].properties.max_key_phrases, 43760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].properties.max_users, 43860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].properties.recognition_modes, 43960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].properties.capture_transition, 44060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].properties.max_buffer_ms, 44160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nModules[i].properties.concurrent_capture, 442d3b8223377b8046280e4c09e728edc600171f941Eric Laurent nModules[i].properties.power_consumption_mw, 443d3b8223377b8046280e4c09e728edc600171f941Eric Laurent nModules[i].properties.trigger_in_event); 44460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 44560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->DeleteLocalRef(implementor); 44660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->DeleteLocalRef(description); 44760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->DeleteLocalRef(uuid); 44860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (newModuleDesc == NULL) { 44960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = SOUNDTRIGGER_STATUS_ERROR; 45060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent goto exit; 45160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 45260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->CallBooleanMethod(jModules, gArrayListMethods.add, newModuleDesc); 45360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 45460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 45560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentexit: 45660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent free(nModules); 45760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return (jint) status; 45860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 45960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 46060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic void 46160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_setup(JNIEnv *env, jobject thiz, jobject weak_this) 46260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 46360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("setup"); 46460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 46560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<JNISoundTriggerCallback> callback = new JNISoundTriggerCallback(env, thiz, weak_this); 46660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 46760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sound_trigger_module_handle_t handle = 46860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (sound_trigger_module_handle_t)env->GetIntField(thiz, gModuleFields.mId); 46960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 47060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<SoundTrigger> module = SoundTrigger::attach(handle, callback); 47160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (module == 0) { 47260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return; 47360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 47460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 47560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent setSoundTrigger(env, thiz, module); 47660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 47760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 47860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic void 47960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_detach(JNIEnv *env, jobject thiz) 48060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 48160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("detach"); 48260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<SoundTrigger> module = setSoundTrigger(env, thiz, 0); 48360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("detach module %p", module.get()); 48460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (module != 0) { 48560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("detach module->detach()"); 48660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent module->detach(); 48760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 48860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 48960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 49060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic void 49160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_finalize(JNIEnv *env, jobject thiz) 49260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 49360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("finalize"); 49460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<SoundTrigger> module = getSoundTrigger(env, thiz); 49560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (module != 0) { 49660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGW("SoundTrigger finalized without being detached"); 49760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 49860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent android_hardware_SoundTrigger_detach(env, thiz); 49960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 50060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 50160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint 50260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz, 50360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jobject jSoundModel, jintArray jHandle) 50460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 50560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jint status = SOUNDTRIGGER_STATUS_OK; 506013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jbyte *nData = NULL; 50760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent struct sound_trigger_sound_model *nSoundModel; 50860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jbyteArray jData; 50960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<MemoryDealer> memoryDealer; 51060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<IMemory> memory; 51160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent size_t size; 5122df0c67152cbf24ced14a963bb935484f424b167George Burgess IV sound_model_handle_t handle = 0; 513d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jobject jUuid; 514d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jstring jUuidString; 515d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha const char *nUuidString; 51660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 51760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("loadSoundModel"); 51860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<SoundTrigger> module = getSoundTrigger(env, thiz); 51960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (module == NULL) { 52060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_ERROR; 52160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 52260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jHandle == NULL) { 52360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_BAD_VALUE; 52460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 52560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jsize jHandleLen = env->GetArrayLength(jHandle); 52660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jHandleLen == 0) { 52760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_BAD_VALUE; 52860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 52960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jint *nHandle = env->GetIntArrayElements(jHandle, NULL); 53060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (nHandle == NULL) { 53160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_ERROR; 53260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 53360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (!env->IsInstanceOf(jSoundModel, gSoundModelClass)) { 53460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = SOUNDTRIGGER_STATUS_BAD_VALUE; 53560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent goto exit; 53660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 53760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent size_t offset; 53860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sound_trigger_sound_model_type_t type; 539d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha if (env->IsInstanceOf(jSoundModel, gKeyphraseSoundModelClass)) { 54060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent offset = sizeof(struct sound_trigger_phrase_sound_model); 54160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent type = SOUND_MODEL_TYPE_KEYPHRASE; 542ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta } else if (env->IsInstanceOf(jSoundModel, gGenericSoundModelClass)) { 543ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta offset = sizeof(struct sound_trigger_generic_sound_model); 544ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta type = SOUND_MODEL_TYPE_GENERIC; 54560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } else { 54660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent offset = sizeof(struct sound_trigger_sound_model); 54760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent type = SOUND_MODEL_TYPE_UNKNOWN; 54860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 549d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha 550d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.uuid); 551d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString); 552d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha nUuidString = env->GetStringUTFChars(jUuidString, NULL); 553d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha sound_trigger_uuid_t nUuid; 554d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha SoundTrigger::stringToGuid(nUuidString, &nUuid); 555d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha env->ReleaseStringUTFChars(jUuidString, nUuidString); 556d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha env->DeleteLocalRef(jUuidString); 557d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha 558d3b8223377b8046280e4c09e728edc600171f941Eric Laurent sound_trigger_uuid_t nVendorUuid; 559d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.vendorUuid); 560d3b8223377b8046280e4c09e728edc600171f941Eric Laurent if (jUuid != NULL) { 561d3b8223377b8046280e4c09e728edc600171f941Eric Laurent jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString); 562d3b8223377b8046280e4c09e728edc600171f941Eric Laurent nUuidString = env->GetStringUTFChars(jUuidString, NULL); 563d3b8223377b8046280e4c09e728edc600171f941Eric Laurent SoundTrigger::stringToGuid(nUuidString, &nVendorUuid); 564d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->ReleaseStringUTFChars(jUuidString, nUuidString); 565d3b8223377b8046280e4c09e728edc600171f941Eric Laurent env->DeleteLocalRef(jUuidString); 566d3b8223377b8046280e4c09e728edc600171f941Eric Laurent } else { 567d3b8223377b8046280e4c09e728edc600171f941Eric Laurent SoundTrigger::stringToGuid("00000000-0000-0000-0000-000000000000", &nVendorUuid); 568d3b8223377b8046280e4c09e728edc600171f941Eric Laurent } 569d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 57060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jData = (jbyteArray)env->GetObjectField(jSoundModel, gSoundModelFields.data); 57160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jData == NULL) { 57260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = SOUNDTRIGGER_STATUS_BAD_VALUE; 57360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent goto exit; 57460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 57560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent size = env->GetArrayLength(jData); 57660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 577013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent nData = env->GetByteArrayElements(jData, NULL); 57860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jData == NULL) { 57960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = SOUNDTRIGGER_STATUS_ERROR; 58060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent goto exit; 58160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 58260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 58360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent memoryDealer = new MemoryDealer(offset + size, "SoundTrigge-JNI::LoadModel"); 58460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (memoryDealer == 0) { 58560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = SOUNDTRIGGER_STATUS_ERROR; 58660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent goto exit; 58760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 58860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent memory = memoryDealer->allocate(offset + size); 58960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (memory == 0 || memory->pointer() == NULL) { 59060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = SOUNDTRIGGER_STATUS_ERROR; 59160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent goto exit; 59260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 59360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 59460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nSoundModel = (struct sound_trigger_sound_model *)memory->pointer(); 59560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 59660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nSoundModel->type = type; 597d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha nSoundModel->uuid = nUuid; 598d3b8223377b8046280e4c09e728edc600171f941Eric Laurent nSoundModel->vendor_uuid = nVendorUuid; 59960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nSoundModel->data_size = size; 60060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nSoundModel->data_offset = offset; 60160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent memcpy((char *)nSoundModel + offset, nData, size); 60260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (type == SOUND_MODEL_TYPE_KEYPHRASE) { 60360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent struct sound_trigger_phrase_sound_model *phraseModel = 60460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (struct sound_trigger_phrase_sound_model *)nSoundModel; 60560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 60660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jobjectArray jPhrases = 607d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha (jobjectArray)env->GetObjectField(jSoundModel, gKeyphraseSoundModelFields.keyphrases); 60860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jPhrases == NULL) { 60960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = SOUNDTRIGGER_STATUS_BAD_VALUE; 61060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent goto exit; 61160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 61260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 61360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent size_t numPhrases = env->GetArrayLength(jPhrases); 61460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent phraseModel->num_phrases = numPhrases; 615d3b8223377b8046280e4c09e728edc600171f941Eric Laurent ALOGV("loadSoundModel numPhrases %zu", numPhrases); 61660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent for (size_t i = 0; i < numPhrases; i++) { 61760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jobject jPhrase = env->GetObjectArrayElement(jPhrases, i); 618d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha phraseModel->phrases[i].id = 619d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha env->GetIntField(jPhrase,gKeyphraseFields.id); 62060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent phraseModel->phrases[i].recognition_mode = 621d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha env->GetIntField(jPhrase,gKeyphraseFields.recognitionModes); 622013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 623013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jintArray jUsers = (jintArray)env->GetObjectField(jPhrase, gKeyphraseFields.users); 624013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent phraseModel->phrases[i].num_users = env->GetArrayLength(jUsers); 625013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jint *nUsers = env->GetIntArrayElements(jUsers, NULL); 626013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent memcpy(phraseModel->phrases[i].users, 627013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent nUsers, 628013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent phraseModel->phrases[i].num_users * sizeof(int)); 629013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->ReleaseIntArrayElements(jUsers, nUsers, 0); 630013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jUsers); 631013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 632d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jstring jLocale = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.locale); 63360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent const char *nLocale = env->GetStringUTFChars(jLocale, NULL); 63460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent strncpy(phraseModel->phrases[i].locale, 63560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nLocale, 63660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUND_TRIGGER_MAX_LOCALE_LEN); 637d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha jstring jText = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.text); 63860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent const char *nText = env->GetStringUTFChars(jText, NULL); 63960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent strncpy(phraseModel->phrases[i].text, 64060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nText, 64160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent SOUND_TRIGGER_MAX_STRING_LEN); 64260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 64360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->ReleaseStringUTFChars(jLocale, nLocale); 64460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->DeleteLocalRef(jLocale); 64560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->ReleaseStringUTFChars(jText, nText); 64660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->DeleteLocalRef(jText); 647d3b8223377b8046280e4c09e728edc600171f941Eric Laurent ALOGV("loadSoundModel phrases %zu text %s locale %s", 64860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent i, phraseModel->phrases[i].text, phraseModel->phrases[i].locale); 649013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jPhrase); 65060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 65160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->DeleteLocalRef(jPhrases); 652ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta } else if (type == SOUND_MODEL_TYPE_GENERIC) { 653ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta /* No initialization needed */ 65460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 65560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = module->loadSoundModel(memory, &handle); 65660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("loadSoundModel status %d handle %d", status, handle); 65760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 65860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentexit: 65960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (nHandle != NULL) { 66060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent nHandle[0] = (jint)handle; 66160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent env->ReleaseIntArrayElements(jHandle, nHandle, NULL); 66260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 66360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (nData != NULL) { 664013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->ReleaseByteArrayElements(jData, nData, NULL); 66560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 66660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return status; 66760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 66860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 66960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint 67060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_unloadSoundModel(JNIEnv *env, jobject thiz, 67160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jint jHandle) 67260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 67360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jint status = SOUNDTRIGGER_STATUS_OK; 67460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("unloadSoundModel"); 67560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<SoundTrigger> module = getSoundTrigger(env, thiz); 67660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (module == NULL) { 67760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_ERROR; 67860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 67960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = module->unloadSoundModel((sound_model_handle_t)jHandle); 68060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 68160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return status; 68260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 68360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 68460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint 68560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_startRecognition(JNIEnv *env, jobject thiz, 686013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jint jHandle, jobject jConfig) 68760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 68860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jint status = SOUNDTRIGGER_STATUS_OK; 68960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("startRecognition"); 69060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<SoundTrigger> module = getSoundTrigger(env, thiz); 69160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (module == NULL) { 69260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_ERROR; 69360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 694013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 695013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent if (!env->IsInstanceOf(jConfig, gRecognitionConfigClass)) { 696013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent return SOUNDTRIGGER_STATUS_BAD_VALUE; 697013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent } 698013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 699013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jbyteArray jData = (jbyteArray)env->GetObjectField(jConfig, gRecognitionConfigFields.data); 70060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jsize dataSize = 0; 701013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jbyte *nData = NULL; 70260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (jData != NULL) { 70360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent dataSize = env->GetArrayLength(jData); 70460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (dataSize == 0) { 70560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_BAD_VALUE; 70660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 707013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent nData = env->GetByteArrayElements(jData, NULL); 70860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (nData == NULL) { 70960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_ERROR; 71060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 711013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent } 712013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 713013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent size_t totalSize = sizeof(struct sound_trigger_recognition_config) + dataSize; 714013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent sp<MemoryDealer> memoryDealer = 715013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent new MemoryDealer(totalSize, "SoundTrigge-JNI::StartRecognition"); 716013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent if (memoryDealer == 0) { 717013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent return SOUNDTRIGGER_STATUS_ERROR; 718013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent } 719013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent sp<IMemory> memory = memoryDealer->allocate(totalSize); 720013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent if (memory == 0 || memory->pointer() == NULL) { 721013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent return SOUNDTRIGGER_STATUS_ERROR; 722013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent } 723013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent if (dataSize != 0) { 724013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent memcpy((char *)memory->pointer() + sizeof(struct sound_trigger_recognition_config), 725013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent nData, 726013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent dataSize); 727013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->ReleaseByteArrayElements(jData, nData, 0); 728013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent } 729013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jData); 730013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent struct sound_trigger_recognition_config *config = 731013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent (struct sound_trigger_recognition_config *)memory->pointer(); 732013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->data_size = dataSize; 733013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->data_offset = sizeof(struct sound_trigger_recognition_config); 73489311c282abbbe647566ae4afbdb9c9851f0bec3Eric Laurent config->capture_requested = env->GetBooleanField(jConfig, 735013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent gRecognitionConfigFields.captureRequested); 736013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 737013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->num_phrases = 0; 738013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jobjectArray jPhrases = 739013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent (jobjectArray)env->GetObjectField(jConfig, gRecognitionConfigFields.keyphrases); 740013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent if (jPhrases != NULL) { 741013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->num_phrases = env->GetArrayLength(jPhrases); 742013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent } 743013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent ALOGV("startRecognition num phrases %d", config->num_phrases); 744013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent for (size_t i = 0; i < config->num_phrases; i++) { 745013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jobject jPhrase = env->GetObjectArrayElement(jPhrases, i); 746013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->phrases[i].id = env->GetIntField(jPhrase, 747013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent gKeyphraseRecognitionExtraFields.id); 748013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->phrases[i].recognition_modes = env->GetIntField(jPhrase, 749013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent gKeyphraseRecognitionExtraFields.recognitionModes); 750d3b8223377b8046280e4c09e728edc600171f941Eric Laurent config->phrases[i].confidence_level = env->GetIntField(jPhrase, 751d3b8223377b8046280e4c09e728edc600171f941Eric Laurent gKeyphraseRecognitionExtraFields.coarseConfidenceLevel); 752013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->phrases[i].num_levels = 0; 753013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jobjectArray jConfidenceLevels = (jobjectArray)env->GetObjectField(jPhrase, 754013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent gKeyphraseRecognitionExtraFields.confidenceLevels); 755013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent if (jConfidenceLevels != NULL) { 756013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->phrases[i].num_levels = env->GetArrayLength(jConfidenceLevels); 75760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 758d3b8223377b8046280e4c09e728edc600171f941Eric Laurent ALOGV("startRecognition phrase %zu num_levels %d", i, config->phrases[i].num_levels); 759013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent for (size_t j = 0; j < config->phrases[i].num_levels; j++) { 760013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent jobject jConfidenceLevel = env->GetObjectArrayElement(jConfidenceLevels, j); 761013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->phrases[i].levels[j].user_id = env->GetIntField(jConfidenceLevel, 762013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent gConfidenceLevelFields.userId); 763013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent config->phrases[i].levels[j].level = env->GetIntField(jConfidenceLevel, 764013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent gConfidenceLevelFields.confidenceLevel); 765013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jConfidenceLevel); 76660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 767d3b8223377b8046280e4c09e728edc600171f941Eric Laurent ALOGV("startRecognition phrases %zu", i); 768013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jConfidenceLevels); 769013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jPhrase); 77060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 771013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent env->DeleteLocalRef(jPhrases); 77260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 77360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = module->startRecognition(jHandle, memory); 77460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return status; 77560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 77660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 77760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentstatic jint 77860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentandroid_hardware_SoundTrigger_stopRecognition(JNIEnv *env, jobject thiz, 77960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jint jHandle) 78060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 78160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent jint status = SOUNDTRIGGER_STATUS_OK; 78260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent ALOGV("stopRecognition"); 78360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent sp<SoundTrigger> module = getSoundTrigger(env, thiz); 78460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent if (module == NULL) { 78560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return SOUNDTRIGGER_STATUS_ERROR; 78660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent } 78760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent status = module->stopRecognition(jHandle); 78860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent return status; 78960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 79060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 79176f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = { 79260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent {"listModules", 79360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "(Ljava/util/ArrayList;)I", 79460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (void *)android_hardware_SoundTrigger_listModules}, 79560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}; 79660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 79760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 79876f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gModuleMethods[] = { 79960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent {"native_setup", 80060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "(Ljava/lang/Object;)V", 80160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (void *)android_hardware_SoundTrigger_setup}, 80260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent {"native_finalize", 80360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "()V", 80460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (void *)android_hardware_SoundTrigger_finalize}, 80560b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent {"detach", 80660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "()V", 80760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (void *)android_hardware_SoundTrigger_detach}, 80860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent {"loadSoundModel", 80960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "(Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;[I)I", 81060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (void *)android_hardware_SoundTrigger_loadSoundModel}, 81160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent {"unloadSoundModel", 81260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "(I)I", 81360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (void *)android_hardware_SoundTrigger_unloadSoundModel}, 81460b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent {"startRecognition", 815013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent "(ILandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;)I", 81660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (void *)android_hardware_SoundTrigger_startRecognition}, 81760b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent {"stopRecognition", 81860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent "(I)I", 81960b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent (void *)android_hardware_SoundTrigger_stopRecognition}, 82060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent}; 82160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 82260b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurentint register_android_hardware_SoundTrigger(JNIEnv *env) 82360b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent{ 824ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList"); 825ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass); 826ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z"); 827ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 828ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass uuidClass = FindClassOrDie(env, "java/util/UUID"); 829ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gUUIDClass = MakeGlobalRefOrDie(env, uuidClass); 830ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gUUIDMethods.toString = GetMethodIDOrDie(env, uuidClass, "toString", "()Ljava/lang/String;"); 831ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 832ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass lClass = FindClassOrDie(env, kSoundTriggerClassPathName); 833ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gSoundTriggerClass = MakeGlobalRefOrDie(env, lClass); 834ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 835ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass moduleClass = FindClassOrDie(env, kModuleClassPathName); 836ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gModuleClass = MakeGlobalRefOrDie(env, moduleClass); 837ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gPostEventFromNative = GetStaticMethodIDOrDie(env, moduleClass, "postEventFromNative", 838ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "(Ljava/lang/Object;IIILjava/lang/Object;)V"); 839ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gModuleFields.mNativeContext = GetFieldIDOrDie(env, moduleClass, "mNativeContext", "J"); 840ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gModuleFields.mId = GetFieldIDOrDie(env, moduleClass, "mId", "I"); 841ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 842ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass modulePropertiesClass = FindClassOrDie(env, kModulePropertiesClassPathName); 843ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gModulePropertiesClass = MakeGlobalRefOrDie(env, modulePropertiesClass); 844ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gModulePropertiesCstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>", 845ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V"); 846ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 847ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass soundModelClass = FindClassOrDie(env, kSoundModelClassPathName); 848ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gSoundModelClass = MakeGlobalRefOrDie(env, soundModelClass); 849ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gSoundModelFields.uuid = GetFieldIDOrDie(env, soundModelClass, "uuid", "Ljava/util/UUID;"); 850ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gSoundModelFields.vendorUuid = GetFieldIDOrDie(env, soundModelClass, "vendorUuid", 851ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "Ljava/util/UUID;"); 852ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gSoundModelFields.data = GetFieldIDOrDie(env, soundModelClass, "data", "[B"); 853ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 854ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta jclass genericSoundModelClass = FindClassOrDie(env, kGenericSoundModelClassPathName); 855ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta gGenericSoundModelClass = MakeGlobalRefOrDie(env, genericSoundModelClass); 856ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta 857ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass keyphraseClass = FindClassOrDie(env, kKeyphraseClassPathName); 858ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseClass = MakeGlobalRefOrDie(env, keyphraseClass); 859ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseFields.id = GetFieldIDOrDie(env, keyphraseClass, "id", "I"); 860ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseFields.recognitionModes = GetFieldIDOrDie(env, keyphraseClass, "recognitionModes", 861ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "I"); 862ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseFields.locale = GetFieldIDOrDie(env, keyphraseClass, "locale", "Ljava/lang/String;"); 863ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseFields.text = GetFieldIDOrDie(env, keyphraseClass, "text", "Ljava/lang/String;"); 864ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseFields.users = GetFieldIDOrDie(env, keyphraseClass, "users", "[I"); 865ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 866ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass keyphraseSoundModelClass = FindClassOrDie(env, kKeyphraseSoundModelClassPathName); 867ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseSoundModelClass = MakeGlobalRefOrDie(env, keyphraseSoundModelClass); 868ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseSoundModelFields.keyphrases = GetFieldIDOrDie(env, keyphraseSoundModelClass, 869d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha "keyphrases", 870d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha "[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;"); 87160b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 872ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass recognitionEventClass = FindClassOrDie(env, kRecognitionEventClassPathName); 873ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gRecognitionEventClass = MakeGlobalRefOrDie(env, recognitionEventClass); 874ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gRecognitionEventCstor = GetMethodIDOrDie(env, recognitionEventClass, "<init>", 875d3b8223377b8046280e4c09e728edc600171f941Eric Laurent "(IIZIIIZLandroid/media/AudioFormat;[B)V"); 87660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 877ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass keyphraseRecognitionEventClass = FindClassOrDie(env, 878ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe kKeyphraseRecognitionEventClassPathName); 879ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionEventClass = MakeGlobalRefOrDie(env, keyphraseRecognitionEventClass); 880ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionEventCstor = GetMethodIDOrDie(env, keyphraseRecognitionEventClass, "<init>", 881d3b8223377b8046280e4c09e728edc600171f941Eric Laurent "(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V"); 882013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 883ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta jclass genericRecognitionEventClass = FindClassOrDie(env, 884ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta kGenericRecognitionEventClassPathName); 885ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta gGenericRecognitionEventClass = MakeGlobalRefOrDie(env, genericRecognitionEventClass); 886ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta gGenericRecognitionEventCstor = GetMethodIDOrDie(env, genericRecognitionEventClass, "<init>", 887ee3fc89a3a7b3a68ae0e9f6f9b8d0fe5e203a873Ryan Bavetta "(IIZIIIZLandroid/media/AudioFormat;[B)V"); 88860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 889ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass keyRecognitionConfigClass = FindClassOrDie(env, kRecognitionConfigClassPathName); 890ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gRecognitionConfigClass = MakeGlobalRefOrDie(env, keyRecognitionConfigClass); 891ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gRecognitionConfigFields.captureRequested = GetFieldIDOrDie(env, keyRecognitionConfigClass, 892ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "captureRequested", "Z"); 893ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gRecognitionConfigFields.keyphrases = GetFieldIDOrDie(env, keyRecognitionConfigClass, 894ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "keyphrases", "[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;"); 895ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gRecognitionConfigFields.data = GetFieldIDOrDie(env, keyRecognitionConfigClass, "data", "[B"); 896ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 897ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass keyphraseRecognitionExtraClass = FindClassOrDie(env, 898ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe kKeyphraseRecognitionExtraClassPathName); 899ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionExtraClass = MakeGlobalRefOrDie(env, keyphraseRecognitionExtraClass); 900ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionExtraCstor = GetMethodIDOrDie(env, keyphraseRecognitionExtraClass, 901ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "<init>", "(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V"); 902ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionExtraFields.id = GetFieldIDOrDie(env, gKeyphraseRecognitionExtraClass, 903ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "id", "I"); 904ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionExtraFields.recognitionModes = GetFieldIDOrDie(env, 905ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionExtraClass, "recognitionModes", "I"); 906ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionExtraFields.coarseConfidenceLevel = GetFieldIDOrDie(env, 907ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionExtraClass, "coarseConfidenceLevel", "I"); 908ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionExtraFields.confidenceLevels = GetFieldIDOrDie(env, 909ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gKeyphraseRecognitionExtraClass, "confidenceLevels", 910ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;"); 911ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 912ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass confidenceLevelClass = FindClassOrDie(env, kConfidenceLevelClassPathName); 913ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gConfidenceLevelClass = MakeGlobalRefOrDie(env, confidenceLevelClass); 914ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gConfidenceLevelCstor = GetMethodIDOrDie(env, confidenceLevelClass, "<init>", "(II)V"); 915ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gConfidenceLevelFields.userId = GetFieldIDOrDie(env, confidenceLevelClass, "userId", "I"); 916ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gConfidenceLevelFields.confidenceLevel = GetFieldIDOrDie(env, confidenceLevelClass, 917013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent "confidenceLevel", "I"); 91860b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 919ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass audioFormatClass = FindClassOrDie(env, kAudioFormatClassPathName); 920ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass); 921a9470c19a9dfe362a201c569f14b669b7aa69ee4Andy Hung gAudioFormatCstor = GetMethodIDOrDie(env, audioFormatClass, "<init>", "(IIII)V"); 922d3b8223377b8046280e4c09e728edc600171f941Eric Laurent 923ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass soundModelEventClass = FindClassOrDie(env, kSoundModelEventClassPathName); 924ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gSoundModelEventClass = MakeGlobalRefOrDie(env, soundModelEventClass); 925ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gSoundModelEventCstor = GetMethodIDOrDie(env, soundModelEventClass, "<init>", "(II[B)V"); 92660b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent 927013f66b92db609fceeff9c8171daca13d057cc95Eric Laurent 928ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe RegisterMethodsOrDie(env, kSoundTriggerClassPathName, gMethods, NELEM(gMethods)); 929ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return RegisterMethodsOrDie(env, kModuleClassPathName, gModuleMethods, NELEM(gModuleMethods)); 93060b62bc5c11c0bfcdf84ca8f5b2053e5747f86bcEric Laurent} 931