1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "SourceDefaultEffect-JNI"
19 
20 #include <utils/Errors.h>
21 #include <utils/Log.h>
22 #include <jni.h>
23 #include <nativehelper/JNIHelp.h>
24 #include <android_runtime/AndroidRuntime.h>
25 #include "media/AudioEffect.h"
26 
27 #include <nativehelper/ScopedUtfChars.h>
28 
29 #include "android_media_AudioEffect.h"
30 
31 using namespace android;
32 
33 static const char* const kClassPathName = "android/media/audiofx/SourceDefaultEffect";
34 
android_media_SourceDefaultEffect_native_setup(JNIEnv * env,jobject,jstring type,jstring uuid,jint priority,jint source,jstring opPackageName,jintArray jId)35 static jint android_media_SourceDefaultEffect_native_setup(JNIEnv *env,
36                                                            jobject /*thiz*/,
37                                                            jstring type,
38                                                            jstring uuid,
39                                                            jint priority,
40                                                            jint source,
41                                                            jstring opPackageName,
42                                                            jintArray jId)
43 {
44     ALOGV("android_media_SourceDefaultEffect_native_setup");
45     status_t lStatus = NO_ERROR;
46     jint* nId = NULL;
47     const char *typeStr = NULL;
48     const char *uuidStr = NULL;
49 
50     ScopedUtfChars opPackageNameStr(env, opPackageName);
51 
52     if (type != NULL) {
53         typeStr = env->GetStringUTFChars(type, NULL);
54         if (typeStr == NULL) {  // Out of memory
55             lStatus = NO_MEMORY;
56             jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
57             goto setup_exit;
58         }
59     }
60 
61     if (uuid != NULL) {
62         uuidStr = env->GetStringUTFChars(uuid, NULL);
63         if (uuidStr == NULL) {  // Out of memory
64             lStatus = NO_MEMORY;
65             jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
66             goto setup_exit;
67         }
68     }
69 
70     if (typeStr == NULL && uuidStr == NULL) {
71         lStatus = BAD_VALUE;
72         goto setup_exit;
73     }
74 
75     nId = reinterpret_cast<jint *>(env->GetPrimitiveArrayCritical(jId, NULL));
76     if (nId == NULL) {
77         ALOGE("setup: Error retrieving id pointer");
78         lStatus = BAD_VALUE;
79         goto setup_exit;
80     }
81 
82     // create the native SourceDefaultEffect.
83     audio_unique_id_t id;
84     lStatus = AudioEffect::addSourceDefaultEffect(typeStr,
85                                                   String16(opPackageNameStr.c_str()),
86                                                   uuidStr,
87                                                   priority,
88                                                   static_cast<audio_source_t>(source),
89                                                   &id);
90     if (lStatus != NO_ERROR) {
91         ALOGE("setup: Error adding SourceDefaultEffect");
92         goto setup_exit;
93     }
94 
95     nId[0] = static_cast<jint>(id);
96 
97 setup_exit:
98     // Final cleanup and return.
99 
100     if (nId != NULL) {
101         env->ReleasePrimitiveArrayCritical(jId, nId, 0);
102         nId = NULL;
103     }
104 
105     if (uuidStr != NULL) {
106         env->ReleaseStringUTFChars(uuid, uuidStr);
107         uuidStr = NULL;
108     }
109 
110     if (typeStr != NULL) {
111         env->ReleaseStringUTFChars(type, typeStr);
112         typeStr = NULL;
113     }
114 
115     return AudioEffectJni::translateNativeErrorToJava(lStatus);
116 }
117 
android_media_SourceDefaultEffect_native_release(JNIEnv *,jobject,jint id)118 static void android_media_SourceDefaultEffect_native_release(JNIEnv */*env*/,
119                                                              jobject /*thiz*/,
120                                                              jint id) {
121     status_t lStatus = AudioEffect::removeSourceDefaultEffect(id);
122     if (lStatus != NO_ERROR) {
123         ALOGW("Error releasing SourceDefaultEffect: %d", lStatus);
124     }
125 }
126 
127 // ----------------------------------------------------------------------------
128 
129 // Dalvik VM type signatures
130 static const JNINativeMethod gMethods[] = {
131     {"native_setup",         "(Ljava/lang/String;Ljava/lang/String;IILjava/lang/String;[I)I",
132                                          (void *)android_media_SourceDefaultEffect_native_setup},
133     {"native_release",       "(I)V",      (void *)android_media_SourceDefaultEffect_native_release},
134 };
135 
136 
137 // ----------------------------------------------------------------------------
138 
register_android_media_SourceDefaultEffect(JNIEnv * env)139 int register_android_media_SourceDefaultEffect(JNIEnv *env)
140 {
141     return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
142 }
143