1948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent/*
2948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * Copyright (C) 2010 The Android Open Source Project
3948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent *
4948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * you may not use this file except in compliance with the License.
6948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * You may obtain a copy of the License at
7948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent *
8948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent *
10948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * Unless required by applicable law or agreed to in writing, software
11948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * See the License for the specific language governing permissions and
14948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * limitations under the License.
15948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent */
16948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
17948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent#include <stdio.h>
18948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
19948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent//#define LOG_NDEBUG 0
20948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent#define LOG_TAG "AudioEffects-JNI"
21948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
22948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent#include <utils/Log.h>
23948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent#include <nativehelper/jni.h>
24948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent#include <nativehelper/JNIHelp.h>
25948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent#include <android_runtime/AndroidRuntime.h>
26948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent#include "media/AudioEffect.h"
27948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
28fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov#include <ScopedUtfChars.h>
29fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov
30948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentusing namespace android;
31948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
32948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent#define AUDIOEFFECT_SUCCESS                      0
330ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define AUDIOEFFECT_ERROR                       (-1)
340ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define AUDIOEFFECT_ERROR_ALREADY_EXISTS        (-2)
350ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define AUDIOEFFECT_ERROR_NO_INIT               (-3)
360ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define AUDIOEFFECT_ERROR_BAD_VALUE             (-4)
370ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define AUDIOEFFECT_ERROR_INVALID_OPERATION     (-5)
380ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define AUDIOEFFECT_ERROR_NO_MEMORY             (-6)
390ca16ef3b8f42f74fdd3d32e7826f9df670bdf90Chih-Hung Hsieh#define AUDIOEFFECT_ERROR_DEAD_OBJECT           (-7)
40948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
41948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// ----------------------------------------------------------------------------
421a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurentstatic const char* const kClassPathName = "android/media/audiofx/AudioEffect";
43948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
44948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstruct fields_t {
45948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // these fields provide access from C++ to the...
46948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jclass    clazzEffect;          // AudioEffect class
47948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jmethodID midPostNativeEvent;   // event post callback method
48948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jfieldID  fidNativeAudioEffect; // stores in Java the native AudioEffect object
49948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jfieldID  fidJniData;           // stores in Java additional resources used by the native AudioEffect
50948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jclass    clazzDesc;            // AudioEffect.Descriptor class
51948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jmethodID midDescCstor;         // AudioEffect.Descriptor class constructor
52948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent};
53948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic fields_t fields;
54948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
55948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstruct effect_callback_cookie {
56948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jclass      audioEffect_class;  // AudioEffect class
57948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jobject     audioEffect_ref;    // AudioEffect object instance
58948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent };
59948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
60948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// ----------------------------------------------------------------------------
61948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentclass AudioEffectJniStorage {
62948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public:
63948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        effect_callback_cookie mCallbackData;
64948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
65948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    AudioEffectJniStorage() {
66948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
67948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
68948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    ~AudioEffectJniStorage() {
69948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
70948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
71948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent};
72948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
73948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
74948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic jint translateError(int code) {
75948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    switch(code) {
76948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case NO_ERROR:
77948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_SUCCESS;
78948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case ALREADY_EXISTS:
79948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_ALREADY_EXISTS;
80948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case NO_INIT:
81948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_NO_INIT;
82948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case BAD_VALUE:
83948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_BAD_VALUE;
84948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case INVALID_OPERATION:
85948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_INVALID_OPERATION;
86948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case NO_MEMORY:
87948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_NO_MEMORY;
88948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case DEAD_OBJECT:
8932d516381c712354ce37a08dbc6c3c7e5f266faaAndy Hung    case FAILED_TRANSACTION: // Hidl crash shows as FAILED_TRANSACTION: -2147483646
90948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_DEAD_OBJECT;
91948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    default:
92948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR;
93948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
94948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
95948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
9676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic Mutex sLock;
97948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
98948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// ----------------------------------------------------------------------------
99948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic void effectCallback(int event, void* user, void *info) {
100948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
101948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    effect_param_t *p;
102948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    int arg1 = 0;
103948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    int arg2 = 0;
104948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jobject obj = NULL;
105948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jbyteArray array = NULL;
106948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jbyte *bytes;
107948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    bool param;
108948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    size_t size;
109948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
110948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    effect_callback_cookie *callbackInfo = (effect_callback_cookie *)user;
111948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    JNIEnv *env = AndroidRuntime::getJNIEnv();
112948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
11371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("effectCallback: callbackInfo %p, audioEffect_ref %p audioEffect_class %p",
114948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            callbackInfo,
115948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            callbackInfo->audioEffect_ref,
116948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            callbackInfo->audioEffect_class);
117948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
118948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (!user || !env) {
1198564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("effectCallback error user %p, env %p", user, env);
120948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return;
121948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
122948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
123948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    switch (event) {
124948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case AudioEffect::EVENT_CONTROL_STATUS_CHANGED:
125948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (info == 0) {
1268564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("EVENT_CONTROL_STATUS_CHANGED info == NULL");
127948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto effectCallback_Exit;
128948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
129948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        param = *(bool *)info;
130948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        arg1 = (int)param;
13171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("EVENT_CONTROL_STATUS_CHANGED");
132948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        break;
133948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case AudioEffect::EVENT_ENABLE_STATUS_CHANGED:
134948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (info == 0) {
1358564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("EVENT_ENABLE_STATUS_CHANGED info == NULL");
136948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto effectCallback_Exit;
137948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
138948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        param = *(bool *)info;
139948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        arg1 = (int)param;
14071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("EVENT_ENABLE_STATUS_CHANGED");
141948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        break;
142948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case AudioEffect::EVENT_PARAMETER_CHANGED:
143948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (info == 0) {
1448564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("EVENT_PARAMETER_CHANGED info == NULL");
145948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto effectCallback_Exit;
146948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
147948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        p = (effect_param_t *)info;
148948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (p->psize == 0 || p->vsize == 0) {
149948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto effectCallback_Exit;
150948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
151948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        // arg1 contains offset of parameter value from start of byte array
152948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        arg1 = sizeof(effect_param_t) + ((p->psize - 1) / sizeof(int) + 1) * sizeof(int);
153948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        size = arg1 + p->vsize;
154948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        array = env->NewByteArray(size);
155948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (array == NULL) {
1563762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("effectCallback: Couldn't allocate byte array for parameter data");
157948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto effectCallback_Exit;
158948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
159948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        bytes = env->GetByteArrayElements(array, NULL);
160948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        memcpy(bytes, p, size);
161948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleaseByteArrayElements(array, bytes, 0);
162948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        obj = array;
16371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("EVENT_PARAMETER_CHANGED");
164948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent       break;
165948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    case AudioEffect::EVENT_ERROR:
1668564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("EVENT_ERROR");
167948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        break;
168948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
169948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
170948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    env->CallStaticVoidMethod(
171948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        callbackInfo->audioEffect_class,
172948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        fields.midPostNativeEvent,
173948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        callbackInfo->audioEffect_ref, event, arg1, arg2, obj);
174948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
175948235c06ed0d49190b2f49d9299b473c4dd61a9Eric LaurenteffectCallback_Exit:
176948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (array) {
177948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->DeleteLocalRef(array);
178948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
179948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
180948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (env->ExceptionCheck()) {
181948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ExceptionDescribe();
182948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ExceptionClear();
183948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
184948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
185948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
186948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// ----------------------------------------------------------------------------
18776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
18876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic sp<AudioEffect> getAudioEffect(JNIEnv* env, jobject thiz)
18976f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent{
19076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    Mutex::Autolock l(sLock);
19176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    AudioEffect* const ae =
19276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent            (AudioEffect*)env->GetLongField(thiz, fields.fidNativeAudioEffect);
19376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    return sp<AudioEffect>(ae);
19476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent}
19576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
19676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic sp<AudioEffect> setAudioEffect(JNIEnv* env, jobject thiz,
19776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent                                    const sp<AudioEffect>& ae)
19876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent{
19976f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    Mutex::Autolock l(sLock);
20076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<AudioEffect> old =
20176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent            (AudioEffect*)env->GetLongField(thiz, fields.fidNativeAudioEffect);
20276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (ae.get()) {
20376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        ae->incStrong((void*)setAudioEffect);
20476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    }
20576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (old != 0) {
20676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        old->decStrong((void*)setAudioEffect);
20776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    }
20876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    env->SetLongField(thiz, fields.fidNativeAudioEffect, (jlong)ae.get());
20976f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    return old;
21076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent}
21176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
21276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent// ----------------------------------------------------------------------------
213948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// This function gets some field IDs, which in turn causes class initialization.
214948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// It is called from a static block in AudioEffect, which won't run until the
215948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// first time an instance of this class is used.
216948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic void
217948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentandroid_media_AudioEffect_native_init(JNIEnv *env)
218948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent{
219948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
22071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("android_media_AudioEffect_native_init");
221948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
222948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    fields.clazzEffect = NULL;
223948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    fields.clazzDesc = NULL;
224948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
225948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Get the AudioEffect class
226948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jclass clazz = env->FindClass(kClassPathName);
227948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (clazz == NULL) {
2283762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find %s", kClassPathName);
229948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return;
230948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
231948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
232948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    fields.clazzEffect = (jclass)env->NewGlobalRef(clazz);
233948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
234948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Get the postEvent method
235948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    fields.midPostNativeEvent = env->GetStaticMethodID(
236948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            fields.clazzEffect,
237948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V");
238948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (fields.midPostNativeEvent == NULL) {
2393762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find AudioEffect.%s", "postEventFromNative");
240948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return;
241948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
242948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
243948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Get the variables fields
244948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    //      nativeTrackInJavaObj
245948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    fields.fidNativeAudioEffect = env->GetFieldID(
246948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            fields.clazzEffect,
247ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat            "mNativeAudioEffect", "J");
248948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (fields.fidNativeAudioEffect == NULL) {
2493762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find AudioEffect.%s", "mNativeAudioEffect");
250948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return;
251948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
252948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    //      fidJniData;
253948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    fields.fidJniData = env->GetFieldID(
254948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            fields.clazzEffect,
255ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat            "mJniData", "J");
256948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (fields.fidJniData == NULL) {
2573762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find AudioEffect.%s", "mJniData");
258948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return;
259948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
260948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
2611a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    clazz = env->FindClass("android/media/audiofx/AudioEffect$Descriptor");
262948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (clazz == NULL) {
2633762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/media/audiofx/AudioEffect$Descriptor class");
264948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return;
265948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
266948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    fields.clazzDesc = (jclass)env->NewGlobalRef(clazz);
267948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
268948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    fields.midDescCstor
269948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            = env->GetMethodID(
270948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    fields.clazzDesc,
271948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    "<init>",
272948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
273948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (fields.midDescCstor == NULL) {
2743762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/media/audiofx/AudioEffect$Descriptor class constructor");
275948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return;
276948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
277948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
278948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
279948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
280948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic jint
281948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentandroid_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
282fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov        jstring type, jstring uuid, jint priority, jint sessionId, jintArray jId,
283fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov        jobjectArray javadesc, jstring opPackageName)
284948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent{
28571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("android_media_AudioEffect_native_setup");
286948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    AudioEffectJniStorage* lpJniStorage = NULL;
287948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    int lStatus = AUDIOEFFECT_ERROR_NO_MEMORY;
28876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<AudioEffect> lpAudioEffect;
289948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jint* nId = NULL;
290948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    const char *typeStr = NULL;
291948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    const char *uuidStr = NULL;
292948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    effect_descriptor_t desc;
293948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jobject jdesc;
294948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    char str[EFFECT_STRING_LEN_MAX];
295948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescType;
296948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescUuid;
297948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescConnect;
298948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescName;
299948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescImplementor;
300948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
301fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov    ScopedUtfChars opPackageNameStr(env, opPackageName);
302fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov
30376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    setAudioEffect(env, thiz, 0);
30476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
305948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (type != NULL) {
306948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        typeStr = env->GetStringUTFChars(type, NULL);
307948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (typeStr == NULL) {  // Out of memory
308948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
309948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto setup_failure;
310948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
311948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
312948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
313948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (uuid != NULL) {
314948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        uuidStr = env->GetStringUTFChars(uuid, NULL);
315948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (uuidStr == NULL) {  // Out of memory
316948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
317948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto setup_failure;
318948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
319948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
320948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
321948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (typeStr == NULL && uuidStr == NULL) {
322948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
323948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto setup_failure;
324948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
325948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
326948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lpJniStorage = new AudioEffectJniStorage();
327948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpJniStorage == NULL) {
3283762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setup: Error creating JNI Storage");
329948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto setup_failure;
330948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
331948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
332948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lpJniStorage->mCallbackData.audioEffect_class = (jclass)env->NewGlobalRef(fields.clazzEffect);
333948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // we use a weak reference so the AudioEffect object can be garbage collected.
334948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lpJniStorage->mCallbackData.audioEffect_ref = env->NewGlobalRef(weak_this);
335948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
33671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("setup: lpJniStorage: %p audioEffect_ref %p audioEffect_class %p, &mCallbackData %p",
337948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            lpJniStorage,
338948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            lpJniStorage->mCallbackData.audioEffect_ref,
339948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            lpJniStorage->mCallbackData.audioEffect_class,
340948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            &lpJniStorage->mCallbackData);
341948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
3422fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    if (jId == NULL) {
3433762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setup: NULL java array for id pointer");
344948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
345948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto setup_failure;
346948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
347948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
348948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // create the native AudioEffect object
349948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lpAudioEffect = new AudioEffect(typeStr,
350fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov                                    String16(opPackageNameStr.c_str()),
351948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                                    uuidStr,
352948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                                    priority,
353948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                                    effectCallback,
354948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                                    &lpJniStorage->mCallbackData,
35533b840444f5a481dd31e129079d3c0cf3acdf80eGlenn Kasten                                    (audio_session_t) sessionId,
35687e901cccac957a19edce9108f85177b85140fbcGlenn Kasten                                    AUDIO_IO_HANDLE_NONE);
35776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpAudioEffect == 0) {
3583762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error creating AudioEffect");
359948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto setup_failure;
360948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
361948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
362948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lStatus = translateError(lpAudioEffect->initCheck());
363948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lStatus != AUDIOEFFECT_SUCCESS && lStatus != AUDIOEFFECT_ERROR_ALREADY_EXISTS) {
3643762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("AudioEffect initCheck failed %d", lStatus);
365948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto setup_failure;
366948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
367948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
3682fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL);
3692fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    if (nId == NULL) {
3703762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setup: Error retrieving id pointer");
3712fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent        lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
3722fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent        goto setup_failure;
3732fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8Eric Laurent    }
374948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    nId[0] = lpAudioEffect->id();
375948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    env->ReleasePrimitiveArrayCritical(jId, nId, 0);
376948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    nId = NULL;
377948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
378948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (typeStr) {
379948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleaseStringUTFChars(type, typeStr);
380948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        typeStr = NULL;
381948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
382948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
383948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (uuidStr) {
384948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleaseStringUTFChars(uuid, uuidStr);
385948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        uuidStr = NULL;
386948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
387948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
388948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // get the effect descriptor
389948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    desc = lpAudioEffect->descriptor();
390948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
391948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    AudioEffect::guidToString(&desc.type, str, EFFECT_STRING_LEN_MAX);
392948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jdescType = env->NewStringUTF(str);
393948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
394948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    AudioEffect::guidToString(&desc.uuid, str, EFFECT_STRING_LEN_MAX);
395948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jdescUuid = env->NewStringUTF(str);
396948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
397948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
398948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jdescConnect = env->NewStringUTF("Auxiliary");
39909f1735fadf985f321abef5fe696d0b80c6b46c7Eric Laurent    } else if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC) {
40009f1735fadf985f321abef5fe696d0b80c6b46c7Eric Laurent        jdescConnect = env->NewStringUTF("Pre Processing");
401948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    } else {
402948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jdescConnect = env->NewStringUTF("Insert");
403948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
404948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
405948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jdescName = env->NewStringUTF(desc.name);
406948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jdescImplementor = env->NewStringUTF(desc.implementor);
407948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
408948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jdesc = env->NewObject(fields.clazzDesc,
409948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                           fields.midDescCstor,
410948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                           jdescType,
411948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                           jdescUuid,
412948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                           jdescConnect,
413948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                           jdescName,
414948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                           jdescImplementor);
415948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    env->DeleteLocalRef(jdescType);
416948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    env->DeleteLocalRef(jdescUuid);
417948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    env->DeleteLocalRef(jdescConnect);
418948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    env->DeleteLocalRef(jdescName);
419948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    env->DeleteLocalRef(jdescImplementor);
420948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (jdesc == NULL) {
4213762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("env->NewObject(fields.clazzDesc, fields.midDescCstor)");
422948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto setup_failure;
423948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
424948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
425948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    env->SetObjectArrayElement(javadesc, 0, jdesc);
426948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
42776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    setAudioEffect(env, thiz, lpAudioEffect);
428948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
429ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    env->SetLongField(thiz, fields.fidJniData, (jlong)lpJniStorage);
430948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
431ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint) AUDIOEFFECT_SUCCESS;
432948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
433948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // failures:
434948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentsetup_failure:
435948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
436948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (nId != NULL) {
437948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleasePrimitiveArrayCritical(jId, nId, 0);
438948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
439948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
440948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpJniStorage) {
44176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_class);
44276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_ref);
443948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        delete lpJniStorage;
444948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
445ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    env->SetLongField(thiz, fields.fidJniData, 0);
446948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
447948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (uuidStr != NULL) {
448948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleaseStringUTFChars(uuid, uuidStr);
449948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
450948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
451948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (typeStr != NULL) {
452948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleaseStringUTFChars(type, typeStr);
453948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
454948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
455ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint)lStatus;
456948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
457948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
458948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
459948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// ----------------------------------------------------------------------------
46076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic void android_media_AudioEffect_native_release(JNIEnv *env,  jobject thiz) {
46176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<AudioEffect> lpAudioEffect = setAudioEffect(env, thiz, 0);
46276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpAudioEffect == 0) {
46376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        return;
464948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
465948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
466948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // delete the JNI data
46776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    AudioEffectJniStorage* lpJniStorage =
46876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent        (AudioEffectJniStorage *)env->GetLongField(thiz, fields.fidJniData);
46976f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
47076f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    // reset the native resources in the Java object so any attempt to access
47176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    // them after a call to release fails.
47276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    env->SetLongField(thiz, fields.fidJniData, 0);
47376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent
474948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpJniStorage) {
475ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        ALOGV("deleting pJniStorage: %p\n", lpJniStorage);
476077999844f306d31d3ea9593b7e7b2f06e7f7483Eric Laurent        env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_class);
477077999844f306d31d3ea9593b7e7b2f06e7f7483Eric Laurent        env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_ref);
478948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        delete lpJniStorage;
479948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
480948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
481948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
482948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// ----------------------------------------------------------------------------
48376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurentstatic void android_media_AudioEffect_native_finalize(JNIEnv *env,  jobject thiz) {
48476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    ALOGV("android_media_AudioEffect_native_finalize jobject: %p\n", thiz);
48576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    android_media_AudioEffect_native_release(env, thiz);
486948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
487948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
488948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic jint
489df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_AudioEffect_native_setEnabled(JNIEnv *env, jobject thiz, jboolean enabled)
490948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent{
49176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<AudioEffect> lpAudioEffect = getAudioEffect(env, thiz);
49276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpAudioEffect == 0) {
493948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jniThrowException(env, "java/lang/IllegalStateException",
494948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            "Unable to retrieve AudioEffect pointer for enable()");
495948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_NO_INIT;
496948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
497948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
498ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint) translateError(lpAudioEffect->setEnabled(enabled));
499948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
500948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
501948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic jboolean
502df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentandroid_media_AudioEffect_native_getEnabled(JNIEnv *env, jobject thiz)
503948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent{
50476f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent  sp<AudioEffect> lpAudioEffect = getAudioEffect(env, thiz);
50576f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent  if (lpAudioEffect == 0) {
506948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jniThrowException(env, "java/lang/IllegalStateException",
507948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            "Unable to retrieve AudioEffect pointer for getEnabled()");
508ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        return JNI_FALSE;
509948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
510948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
511ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    if (lpAudioEffect->getEnabled()) {
512ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        return JNI_TRUE;
513ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    } else {
514ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        return JNI_FALSE;
515ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    }
516948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
517948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
518948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
519948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic jboolean
520948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentandroid_media_AudioEffect_native_hasControl(JNIEnv *env, jobject thiz)
521948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent{
52276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent  sp<AudioEffect> lpAudioEffect = getAudioEffect(env, thiz);
52376f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent  if (lpAudioEffect == 0) {
524948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jniThrowException(env, "java/lang/IllegalStateException",
525df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            "Unable to retrieve AudioEffect pointer for hasControl()");
526ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        return JNI_FALSE;
527948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
528948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
529948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpAudioEffect->initCheck() == NO_ERROR) {
530ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        return JNI_TRUE;
531948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    } else {
532ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        return JNI_FALSE;
533948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
534948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
535948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
536948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic jint android_media_AudioEffect_native_setParameter(JNIEnv *env,
537ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat        jobject thiz, jint psize, jbyteArray pJavaParam, jint vsize,
538948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jbyteArray pJavaValue) {
539948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // retrieve the AudioEffect object
540948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jbyte* lpValue = NULL;
541948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jbyte* lpParam = NULL;
542948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jint lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
543948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    effect_param_t *p;
544948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    int voffset;
545948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
54676f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<AudioEffect> lpAudioEffect = getAudioEffect(env, thiz);
54776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpAudioEffect == 0) {
548948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jniThrowException(env, "java/lang/IllegalStateException",
549948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                "Unable to retrieve AudioEffect pointer for setParameter()");
550948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_NO_INIT;
551948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
552948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
553948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (psize == 0 || vsize == 0 || pJavaParam == NULL || pJavaValue == NULL) {
554948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_BAD_VALUE;
555948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
556948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
557948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // get the pointer for the param from the java array
558948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lpParam = (jbyte *) env->GetPrimitiveArrayCritical(pJavaParam, NULL);
559948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpParam == NULL) {
5603762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setParameter: Error retrieving param pointer");
561948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto setParameter_Exit;
562948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
563948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
564948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // get the pointer for the value from the java array
565948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lpValue = (jbyte *) env->GetPrimitiveArrayCritical(pJavaValue, NULL);
566948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpValue == NULL) {
5673762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("setParameter: Error retrieving value pointer");
568948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto setParameter_Exit;
569948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
570948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
571948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    voffset = ((psize - 1) / sizeof(int) + 1) * sizeof(int);
572948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    p = (effect_param_t *) malloc(sizeof(effect_param_t) + voffset + vsize);
573948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    memcpy(p->data, lpParam, psize);
574948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    p->psize = psize;
575ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    memcpy(p->data + voffset, lpValue, vsize);
576948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    p->vsize = vsize;
577948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
578948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lStatus = lpAudioEffect->setParameter(p);
579948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lStatus == NO_ERROR) {
580948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        lStatus = p->status;
581948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
582948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
583948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    free(p);
584948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
585948235c06ed0d49190b2f49d9299b473c4dd61a9Eric LaurentsetParameter_Exit:
586948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
587948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpParam != NULL) {
588948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleasePrimitiveArrayCritical(pJavaParam, lpParam, 0);
589948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
590948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpValue != NULL) {
591948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleasePrimitiveArrayCritical(pJavaValue, lpValue, 0);
592948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
593ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint) translateError(lStatus);
594948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
595948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
596948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic jint
597948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentandroid_media_AudioEffect_native_getParameter(JNIEnv *env,
598602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        jobject thiz, jint psize, jbyteArray pJavaParam,
599602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        jint vsize, jbyteArray pJavaValue) {
600948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // retrieve the AudioEffect object
601948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jbyte* lpParam = NULL;
602948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jbyte* lpValue = NULL;
603948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jint lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
604948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    effect_param_t *p;
605948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    int voffset;
606948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
60776f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<AudioEffect> lpAudioEffect = getAudioEffect(env, thiz);
60876f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpAudioEffect == 0) {
609948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jniThrowException(env, "java/lang/IllegalStateException",
610948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                "Unable to retrieve AudioEffect pointer for getParameter()");
611948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_NO_INIT;
612948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
613948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
614602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    if (psize == 0 || vsize == 0 || pJavaParam == NULL || pJavaValue == NULL) {
615948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_BAD_VALUE;
616948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
617948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
618948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // get the pointer for the param from the java array
619948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lpParam = (jbyte *) env->GetPrimitiveArrayCritical(pJavaParam, NULL);
620948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpParam == NULL) {
6213762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("getParameter: Error retrieving param pointer");
622948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto getParameter_Exit;
623948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
624948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
625948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // get the pointer for the value from the java array
626948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lpValue = (jbyte *) env->GetPrimitiveArrayCritical(pJavaValue, NULL);
627948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpValue == NULL) {
6283762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("getParameter: Error retrieving value pointer");
629948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto getParameter_Exit;
630948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
631948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
632948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    voffset = ((psize - 1) / sizeof(int) + 1) * sizeof(int);
633602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    p = (effect_param_t *) malloc(sizeof(effect_param_t) + voffset + vsize);
634948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    memcpy(p->data, lpParam, psize);
635948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    p->psize = psize;
636602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    p->vsize = vsize;
637948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
638948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    lStatus = lpAudioEffect->getParameter(p);
639948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lStatus == NO_ERROR) {
640948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        lStatus = p->status;
641948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (lStatus == NO_ERROR) {
642948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            memcpy(lpValue, p->data + voffset, p->vsize);
643602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            vsize = p->vsize;
644948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
645948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
646948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
647948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    free(p);
648948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
649948235c06ed0d49190b2f49d9299b473c4dd61a9Eric LaurentgetParameter_Exit:
650948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
651948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpParam != NULL) {
652948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleasePrimitiveArrayCritical(pJavaParam, lpParam, 0);
653948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
654948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (lpValue != NULL) {
655948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleasePrimitiveArrayCritical(pJavaValue, lpValue, 0);
656948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
657948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
658602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    if (lStatus == NO_ERROR) {
659602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        return vsize;
660602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    }
661ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    return (jint) translateError(lStatus);
662948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
663948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
664948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic jint android_media_AudioEffect_native_command(JNIEnv *env, jobject thiz,
665602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        jint cmdCode, jint cmdSize, jbyteArray jCmdData, jint replySize,
666948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jbyteArray jReplyData) {
667948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jbyte* pCmdData = NULL;
668948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jbyte* pReplyData = NULL;
669948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jint lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
670948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
67176f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    sp<AudioEffect> lpAudioEffect = getAudioEffect(env, thiz);
67276f81331886c0972e5f7432e4edd8c36ef1048e6Eric Laurent    if (lpAudioEffect == 0) {
673948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jniThrowException(env, "java/lang/IllegalStateException",
674948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                "Unable to retrieve AudioEffect pointer for setParameter()");
675948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_NO_INIT;
676948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
677948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
678602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    if ((cmdSize != 0 && jCmdData == NULL) || (replySize != 0 && jReplyData == NULL)) {
679948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return AUDIOEFFECT_ERROR_BAD_VALUE;
680948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
681948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
682948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // get the pointer for the command from the java array
683948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (cmdSize != 0) {
684948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        pCmdData = (jbyte *) env->GetPrimitiveArrayCritical(jCmdData, NULL);
685948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (pCmdData == NULL) {
6863762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("setParameter: Error retrieving command pointer");
687948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto command_Exit;
688948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
689948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
690948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
691948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // get the pointer for the reply from the java array
692602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    if (replySize != 0 && jReplyData != NULL) {
693948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        pReplyData = (jbyte *) env->GetPrimitiveArrayCritical(jReplyData, NULL);
694948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (pReplyData == NULL) {
6953762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("setParameter: Error retrieving reply pointer");
696948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto command_Exit;
697948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
698948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
699948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
700a4c72acfbc6c06588dd26cf41e67a834fc0a54f9Eric Laurent    lStatus = translateError(lpAudioEffect->command((uint32_t)cmdCode,
701a4c72acfbc6c06588dd26cf41e67a834fc0a54f9Eric Laurent                                                    (uint32_t)cmdSize,
702a4c72acfbc6c06588dd26cf41e67a834fc0a54f9Eric Laurent                                                    pCmdData,
703602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                                                    (uint32_t *)&replySize,
704a4c72acfbc6c06588dd26cf41e67a834fc0a54f9Eric Laurent                                                    pReplyData));
705948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
706948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentcommand_Exit:
707948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
708948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (pCmdData != NULL) {
709948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleasePrimitiveArrayCritical(jCmdData, pCmdData, 0);
710948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
711948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (pReplyData != NULL) {
712948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->ReleasePrimitiveArrayCritical(jReplyData, pReplyData, 0);
713948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
714948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
715602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    if (lStatus == NO_ERROR) {
716602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        return replySize;
717602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    }
718948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    return lStatus;
719948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
720948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
721948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentstatic jobjectArray
7224fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurentandroid_media_AudioEffect_native_queryEffects(JNIEnv *env, jclass clazz __unused)
723948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent{
724948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    effect_descriptor_t desc;
725948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    char str[EFFECT_STRING_LEN_MAX];
7264fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    uint32_t totalEffectsCount = 0;
7274fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    uint32_t returnedEffectsCount = 0;
728948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    uint32_t i = 0;
729948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescType;
730948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescUuid;
731948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescConnect;
732948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescName;
733948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jstring jdescImplementor;
734948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jobject jdesc;
7354fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    jobjectArray ret;
736948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
7374fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    if (AudioEffect::queryNumberEffects(&totalEffectsCount) != NO_ERROR) {
7384526f0de0a5698832719f16158bed57ad209d4f2Peter Karlsson        return NULL;
7394526f0de0a5698832719f16158bed57ad209d4f2Peter Karlsson    }
7404526f0de0a5698832719f16158bed57ad209d4f2Peter Karlsson
7414fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    jobjectArray temp = env->NewObjectArray(totalEffectsCount, fields.clazzDesc, NULL);
7424fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    if (temp == NULL) {
7434fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent        return temp;
744948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
745948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
7464fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    ALOGV("queryEffects() totalEffectsCount: %d", totalEffectsCount);
747948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
7484fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    for (i = 0; i < totalEffectsCount; i++) {
74953334cdb81bab4a4dfd0a41d2ef50709015a36c8Eric Laurent        if (AudioEffect::queryEffect(i, &desc) != NO_ERROR) {
750948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto queryEffects_failure;
751948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
752948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
7530f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
7540f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            jdescConnect = env->NewStringUTF("Auxiliary");
7550f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        } else if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT) {
7560f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            jdescConnect = env->NewStringUTF("Insert");
7570f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        } else if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC) {
7580f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            jdescConnect = env->NewStringUTF("Pre Processing");
7590f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        } else {
7600f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            continue;
7610f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        }
7620f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
763948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        AudioEffect::guidToString(&desc.type, str, EFFECT_STRING_LEN_MAX);
764948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jdescType = env->NewStringUTF(str);
765948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
766948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        AudioEffect::guidToString(&desc.uuid, str, EFFECT_STRING_LEN_MAX);
767948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jdescUuid = env->NewStringUTF(str);
768948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
769948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jdescName = env->NewStringUTF(desc.name);
770948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jdescImplementor = env->NewStringUTF(desc.implementor);
771948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
772948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        jdesc = env->NewObject(fields.clazzDesc,
773948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                               fields.midDescCstor,
774948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                               jdescType,
775948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                               jdescUuid,
776948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                               jdescConnect,
777948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                               jdescName,
778948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                               jdescImplementor);
779948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->DeleteLocalRef(jdescType);
780948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->DeleteLocalRef(jdescUuid);
781948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->DeleteLocalRef(jdescConnect);
782948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->DeleteLocalRef(jdescName);
783948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        env->DeleteLocalRef(jdescImplementor);
784948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (jdesc == NULL) {
7853762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("env->NewObject(fields.clazzDesc, fields.midDescCstor)");
786948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            goto queryEffects_failure;
787948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
788948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
7894fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent        env->SetObjectArrayElement(temp, returnedEffectsCount++, jdesc);
790948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent   }
791948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
7924fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    if (returnedEffectsCount == 0) {
7934fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent        goto queryEffects_failure;
7944fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    }
7954fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    ret = env->NewObjectArray(returnedEffectsCount, fields.clazzDesc, NULL);
7964fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    if (ret == NULL) {
7974fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent        goto queryEffects_failure;
7984fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    }
7994fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    for (i = 0; i < returnedEffectsCount; i++) {
8004fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent        env->SetObjectArrayElement(ret, i, env->GetObjectArrayElement(temp, i));
8014fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    }
8024fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    env->DeleteLocalRef(temp);
803948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    return ret;
804948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
805948235c06ed0d49190b2f49d9299b473c4dd61a9Eric LaurentqueryEffects_failure:
806948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
8074fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent    if (temp != NULL) {
8084fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent        env->DeleteLocalRef(temp);
809948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
810948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    return NULL;
811948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
812948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
813948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
8140f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
8150f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
8160f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurentstatic jobjectArray
8174fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurentandroid_media_AudioEffect_native_queryPreProcessings(JNIEnv *env, jclass clazz __unused,
8184fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurent                                                     jint audioSession)
8190f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent{
820b27a8a5bcc40054f6d775d070bc2de6eb996d1c2Eric Laurent    effect_descriptor_t *descriptors = new effect_descriptor_t[AudioEffect::kMaxPreProcessing];
821b27a8a5bcc40054f6d775d070bc2de6eb996d1c2Eric Laurent    uint32_t numEffects = AudioEffect::kMaxPreProcessing;
8220f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
82333b840444f5a481dd31e129079d3c0cf3acdf80eGlenn Kasten    status_t status = AudioEffect::queryDefaultPreProcessing((audio_session_t) audioSession,
8240f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                                           descriptors,
8250f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                                           &numEffects);
8260f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    if (status != NO_ERROR || numEffects == 0) {
8270f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        delete[] descriptors;
8280f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        return NULL;
8290f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
83071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("queryDefaultPreProcessing() got %d effects", numEffects);
8310f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
8320f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    jobjectArray ret = env->NewObjectArray(numEffects, fields.clazzDesc, NULL);
8330f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    if (ret == NULL) {
8340f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        delete[] descriptors;
8350f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        return ret;
8360f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
8370f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
8380f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    char str[EFFECT_STRING_LEN_MAX];
8390f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    jstring jdescType;
8400f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    jstring jdescUuid;
8410f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    jstring jdescConnect;
8420f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    jstring jdescName;
8430f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    jstring jdescImplementor;
8440f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    jobject jdesc;
8450f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
8460f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    for (uint32_t i = 0; i < numEffects; i++) {
8470f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
8480f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        AudioEffect::guidToString(&descriptors[i].type, str, EFFECT_STRING_LEN_MAX);
8490f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        jdescType = env->NewStringUTF(str);
8500f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        AudioEffect::guidToString(&descriptors[i].uuid, str, EFFECT_STRING_LEN_MAX);
8510f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        jdescUuid = env->NewStringUTF(str);
8520f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        jdescConnect = env->NewStringUTF("Pre Processing");
8530f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        jdescName = env->NewStringUTF(descriptors[i].name);
8540f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        jdescImplementor = env->NewStringUTF(descriptors[i].implementor);
8550f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
8560f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        jdesc = env->NewObject(fields.clazzDesc,
8570f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                               fields.midDescCstor,
8580f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                               jdescType,
8590f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                               jdescUuid,
8600f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                               jdescConnect,
8610f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                               jdescName,
8620f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                               jdescImplementor);
8630f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        env->DeleteLocalRef(jdescType);
8640f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        env->DeleteLocalRef(jdescUuid);
8650f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        env->DeleteLocalRef(jdescConnect);
8660f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        env->DeleteLocalRef(jdescName);
8670f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        env->DeleteLocalRef(jdescImplementor);
8680f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        if (jdesc == NULL) {
8693762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("env->NewObject(fields.clazzDesc, fields.midDescCstor)");
8700f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            env->DeleteLocalRef(ret);
8710f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            return NULL;;
8720f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        }
8730f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
8740f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        env->SetObjectArrayElement(ret, i, jdesc);
8750f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent   }
8760f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
8770f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent   return ret;
8780f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent}
8790f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
880948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// ----------------------------------------------------------------------------
881948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
882948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// Dalvik VM type signatures
88376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = {
884948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    {"native_init",          "()V",      (void *)android_media_AudioEffect_native_init},
885fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov    {"native_setup",         "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;II[I[Ljava/lang/Object;Ljava/lang/String;)I",
886948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                                         (void *)android_media_AudioEffect_native_setup},
887948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    {"native_finalize",      "()V",      (void *)android_media_AudioEffect_native_finalize},
888948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    {"native_release",       "()V",      (void *)android_media_AudioEffect_native_release},
889df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_setEnabled",    "(Z)I",      (void *)android_media_AudioEffect_native_setEnabled},
890df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {"native_getEnabled",    "()Z",      (void *)android_media_AudioEffect_native_getEnabled},
891948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    {"native_hasControl",    "()Z",      (void *)android_media_AudioEffect_native_hasControl},
892948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    {"native_setParameter",  "(I[BI[B)I",  (void *)android_media_AudioEffect_native_setParameter},
893602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    {"native_getParameter",  "(I[BI[B)I",  (void *)android_media_AudioEffect_native_getParameter},
894602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    {"native_command",       "(II[BI[B)I", (void *)android_media_AudioEffect_native_command},
895948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    {"native_query_effects", "()[Ljava/lang/Object;", (void *)android_media_AudioEffect_native_queryEffects},
8960f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    {"native_query_pre_processing", "(I)[Ljava/lang/Object;",
8970f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            (void *)android_media_AudioEffect_native_queryPreProcessings},
898948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent};
899948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
900948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
901948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent// ----------------------------------------------------------------------------
902948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
903df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentextern int register_android_media_visualizer(JNIEnv *env);
904df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
905948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentint register_android_media_AudioEffect(JNIEnv *env)
906948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent{
907948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
908948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
909948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
9104fc28d78cb925c2780abf02c6826e77f8f8a230aEric Laurentjint JNI_OnLoad(JavaVM* vm, void* reserved __unused)
911948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent{
912948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
913948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    JNIEnv* env = NULL;
914948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    jint result = -1;
915948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
916948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
9173762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("ERROR: GetEnv failed\n");
918948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto bail;
919948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
920948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    assert(env != NULL);
921948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
922948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    if (register_android_media_AudioEffect(env) < 0) {
9233762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("ERROR: AudioEffect native registration failed\n");
924948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        goto bail;
925948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
926948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
927df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    if (register_android_media_visualizer(env) < 0) {
9283762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("ERROR: Visualizer native registration failed\n");
929df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        goto bail;
930df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
931df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
932948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /* success -- return valid version number */
933948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    result = JNI_VERSION_1_4;
934948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
935948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentbail:
936948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    return result;
937948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
938948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
939