Loading media/java/android/media/audiofx/DefaultEffect.java +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ package android.media.audiofx; * <p>Applications should not use the DefaultEffect class directly but one of its derived classes * to control specific types of defaults: * <ul> * <li> {@link android.media.audiofx.SourceDefaultEffect}</li> * <li> {@link android.media.audiofx.StreamDefaultEffect}</li> * </ul> * <p>Creating a DefaultEffect object will register the corresponding effect engine as a default Loading media/java/android/media/audiofx/SourceDefaultEffect.java 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media.audiofx; import android.annotation.RequiresPermission; import android.app.ActivityThread; import android.util.Log; import java.util.UUID; /** * SourceDefaultEffect is a default effect that attaches automatically to all AudioRecord and * MediaRecorder instances of a given source type. * <p>see {@link android.media.audiofx.DefaultEffect} class for more details on default effects. * @hide */ public class SourceDefaultEffect extends DefaultEffect { static { System.loadLibrary("audioeffect_jni"); } private final static String TAG = "SourceDefaultEffect-JAVA"; /** * Class constructor. * * @param type type of effect engine to be default. This parameter is ignored if uuid is set, * and can be set to {@link android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL} * in that case. * @param uuid unique identifier of a particular effect implementation to be default. This * parameter can be set to * {@link android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL}, in which case only * the type will be used to select the effect. * @param priority the priority level requested by the application for controlling the effect * engine. As the same engine can be shared by several applications, this parameter * indicates how much the requesting application needs control of effect parameters. * The normal priority is 0, above normal is a positive number, below normal a * negative number. * @param source a MediaRecorder.AudioSource.* constant from * {@link android.media.MediaRecorder.AudioSource} indicating * what sources the given effect should attach to by default. Note that similar * sources may share defaults. * * @throws java.lang.IllegalArgumentException * @throws java.lang.UnsupportedOperationException * @throws java.lang.RuntimeException */ @RequiresPermission(value = android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS, conditional = true) // Android Things uses an alternate permission. public SourceDefaultEffect(UUID type, UUID uuid, int priority, int source) { int[] id = new int[1]; int initResult = native_setup(type.toString(), uuid.toString(), priority, source, ActivityThread.currentOpPackageName(), id); if (initResult != AudioEffect.SUCCESS) { Log.e(TAG, "Error code " + initResult + " when initializing SourceDefaultEffect"); switch (initResult) { case AudioEffect.ERROR_BAD_VALUE: throw (new IllegalArgumentException( "Source, type uuid, or implementation uuid not supported.")); case AudioEffect.ERROR_INVALID_OPERATION: throw (new UnsupportedOperationException( "Effect library not loaded")); default: throw (new RuntimeException( "Cannot initialize effect engine for type: " + type + " Error: " + initResult)); } } mId = id[0]; } /** * Releases the native SourceDefaultEffect resources. It is a good practice to * release the default effect when done with use as control can be returned to * other applications or the native resources released. */ public void release() { native_release(mId); } @Override protected void finalize() { release(); } // --------------------------------------------------------- // Native methods called from the Java side // -------------------- private native final int native_setup(String type, String uuid, int priority, int source, String opPackageName, int[] id); private native final void native_release(int id); } media/jni/audioeffect/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ cc_library_shared { srcs: [ "android_media_AudioEffect.cpp", "android_media_SourceDefaultEffect.cpp", "android_media_StreamDefaultEffect.cpp", "android_media_Visualizer.cpp", ], Loading media/jni/audioeffect/android_media_AudioEffect.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -907,6 +907,7 @@ static const JNINativeMethod gMethods[] = { // ---------------------------------------------------------------------------- extern int register_android_media_SourceDefaultEffect(JNIEnv *env); extern int register_android_media_StreamDefaultEffect(JNIEnv *env); extern int register_android_media_visualizer(JNIEnv *env); Loading @@ -932,6 +933,11 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved __unused) goto bail; } if (register_android_media_SourceDefaultEffect(env) < 0) { ALOGE("ERROR: SourceDefaultEffect native registration failed\n"); goto bail; } if (register_android_media_StreamDefaultEffect(env) < 0) { ALOGE("ERROR: StreamDefaultEffect native registration failed\n"); goto bail; Loading media/jni/audioeffect/android_media_SourceDefaultEffect.cpp 0 → 100644 +142 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "SourceDefaultEffect-JNI" #include <utils/Errors.h> #include <utils/Log.h> #include <jni.h> #include <nativehelper/JNIHelp.h> #include <android_runtime/AndroidRuntime.h> #include "media/AudioEffect.h" #include <nativehelper/ScopedUtfChars.h> #include "android_media_AudioEffect.h" using namespace android; static const char* const kClassPathName = "android/media/audiofx/SourceDefaultEffect"; static jint android_media_SourceDefaultEffect_native_setup(JNIEnv *env, jobject /*thiz*/, jstring type, jstring uuid, jint priority, jint source, jstring opPackageName, jintArray jId) { ALOGV("android_media_SourceDefaultEffect_native_setup"); status_t lStatus = NO_ERROR; jint* nId = NULL; const char *typeStr = NULL; const char *uuidStr = NULL; ScopedUtfChars opPackageNameStr(env, opPackageName); if (type != NULL) { typeStr = env->GetStringUTFChars(type, NULL); if (typeStr == NULL) { // Out of memory lStatus = NO_MEMORY; jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); goto setup_exit; } } if (uuid != NULL) { uuidStr = env->GetStringUTFChars(uuid, NULL); if (uuidStr == NULL) { // Out of memory lStatus = NO_MEMORY; jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); goto setup_exit; } } if (typeStr == NULL && uuidStr == NULL) { lStatus = BAD_VALUE; goto setup_exit; } nId = reinterpret_cast<jint *>(env->GetPrimitiveArrayCritical(jId, NULL)); if (nId == NULL) { ALOGE("setup: Error retrieving id pointer"); lStatus = BAD_VALUE; goto setup_exit; } // create the native SourceDefaultEffect. audio_unique_id_t id; lStatus = AudioEffect::addSourceDefaultEffect(typeStr, String16(opPackageNameStr.c_str()), uuidStr, priority, static_cast<audio_source_t>(source), &id); if (lStatus != NO_ERROR) { ALOGE("setup: Error adding SourceDefaultEffect"); goto setup_exit; } nId[0] = static_cast<jint>(id); setup_exit: // Final cleanup and return. if (nId != NULL) { env->ReleasePrimitiveArrayCritical(jId, nId, 0); nId = NULL; } if (uuidStr != NULL) { env->ReleaseStringUTFChars(uuid, uuidStr); uuidStr = NULL; } if (typeStr != NULL) { env->ReleaseStringUTFChars(type, typeStr); typeStr = NULL; } return AudioEffectJni::translateNativeErrorToJava(lStatus); } static void android_media_SourceDefaultEffect_native_release(JNIEnv */*env*/, jobject /*thiz*/, jint id) { status_t lStatus = AudioEffect::removeSourceDefaultEffect(id); if (lStatus != NO_ERROR) { ALOGW("Error releasing SourceDefaultEffect: %d", lStatus); } } // ---------------------------------------------------------------------------- // Dalvik VM type signatures static const JNINativeMethod gMethods[] = { {"native_setup", "(Ljava/lang/String;Ljava/lang/String;IILjava/lang/String;[I)I", (void *)android_media_SourceDefaultEffect_native_setup}, {"native_release", "(I)V", (void *)android_media_SourceDefaultEffect_native_release}, }; // ---------------------------------------------------------------------------- int register_android_media_SourceDefaultEffect(JNIEnv *env) { return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); } Loading
media/java/android/media/audiofx/DefaultEffect.java +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ package android.media.audiofx; * <p>Applications should not use the DefaultEffect class directly but one of its derived classes * to control specific types of defaults: * <ul> * <li> {@link android.media.audiofx.SourceDefaultEffect}</li> * <li> {@link android.media.audiofx.StreamDefaultEffect}</li> * </ul> * <p>Creating a DefaultEffect object will register the corresponding effect engine as a default Loading
media/java/android/media/audiofx/SourceDefaultEffect.java 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media.audiofx; import android.annotation.RequiresPermission; import android.app.ActivityThread; import android.util.Log; import java.util.UUID; /** * SourceDefaultEffect is a default effect that attaches automatically to all AudioRecord and * MediaRecorder instances of a given source type. * <p>see {@link android.media.audiofx.DefaultEffect} class for more details on default effects. * @hide */ public class SourceDefaultEffect extends DefaultEffect { static { System.loadLibrary("audioeffect_jni"); } private final static String TAG = "SourceDefaultEffect-JAVA"; /** * Class constructor. * * @param type type of effect engine to be default. This parameter is ignored if uuid is set, * and can be set to {@link android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL} * in that case. * @param uuid unique identifier of a particular effect implementation to be default. This * parameter can be set to * {@link android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL}, in which case only * the type will be used to select the effect. * @param priority the priority level requested by the application for controlling the effect * engine. As the same engine can be shared by several applications, this parameter * indicates how much the requesting application needs control of effect parameters. * The normal priority is 0, above normal is a positive number, below normal a * negative number. * @param source a MediaRecorder.AudioSource.* constant from * {@link android.media.MediaRecorder.AudioSource} indicating * what sources the given effect should attach to by default. Note that similar * sources may share defaults. * * @throws java.lang.IllegalArgumentException * @throws java.lang.UnsupportedOperationException * @throws java.lang.RuntimeException */ @RequiresPermission(value = android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS, conditional = true) // Android Things uses an alternate permission. public SourceDefaultEffect(UUID type, UUID uuid, int priority, int source) { int[] id = new int[1]; int initResult = native_setup(type.toString(), uuid.toString(), priority, source, ActivityThread.currentOpPackageName(), id); if (initResult != AudioEffect.SUCCESS) { Log.e(TAG, "Error code " + initResult + " when initializing SourceDefaultEffect"); switch (initResult) { case AudioEffect.ERROR_BAD_VALUE: throw (new IllegalArgumentException( "Source, type uuid, or implementation uuid not supported.")); case AudioEffect.ERROR_INVALID_OPERATION: throw (new UnsupportedOperationException( "Effect library not loaded")); default: throw (new RuntimeException( "Cannot initialize effect engine for type: " + type + " Error: " + initResult)); } } mId = id[0]; } /** * Releases the native SourceDefaultEffect resources. It is a good practice to * release the default effect when done with use as control can be returned to * other applications or the native resources released. */ public void release() { native_release(mId); } @Override protected void finalize() { release(); } // --------------------------------------------------------- // Native methods called from the Java side // -------------------- private native final int native_setup(String type, String uuid, int priority, int source, String opPackageName, int[] id); private native final void native_release(int id); }
media/jni/audioeffect/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ cc_library_shared { srcs: [ "android_media_AudioEffect.cpp", "android_media_SourceDefaultEffect.cpp", "android_media_StreamDefaultEffect.cpp", "android_media_Visualizer.cpp", ], Loading
media/jni/audioeffect/android_media_AudioEffect.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -907,6 +907,7 @@ static const JNINativeMethod gMethods[] = { // ---------------------------------------------------------------------------- extern int register_android_media_SourceDefaultEffect(JNIEnv *env); extern int register_android_media_StreamDefaultEffect(JNIEnv *env); extern int register_android_media_visualizer(JNIEnv *env); Loading @@ -932,6 +933,11 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved __unused) goto bail; } if (register_android_media_SourceDefaultEffect(env) < 0) { ALOGE("ERROR: SourceDefaultEffect native registration failed\n"); goto bail; } if (register_android_media_StreamDefaultEffect(env) < 0) { ALOGE("ERROR: StreamDefaultEffect native registration failed\n"); goto bail; Loading
media/jni/audioeffect/android_media_SourceDefaultEffect.cpp 0 → 100644 +142 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "SourceDefaultEffect-JNI" #include <utils/Errors.h> #include <utils/Log.h> #include <jni.h> #include <nativehelper/JNIHelp.h> #include <android_runtime/AndroidRuntime.h> #include "media/AudioEffect.h" #include <nativehelper/ScopedUtfChars.h> #include "android_media_AudioEffect.h" using namespace android; static const char* const kClassPathName = "android/media/audiofx/SourceDefaultEffect"; static jint android_media_SourceDefaultEffect_native_setup(JNIEnv *env, jobject /*thiz*/, jstring type, jstring uuid, jint priority, jint source, jstring opPackageName, jintArray jId) { ALOGV("android_media_SourceDefaultEffect_native_setup"); status_t lStatus = NO_ERROR; jint* nId = NULL; const char *typeStr = NULL; const char *uuidStr = NULL; ScopedUtfChars opPackageNameStr(env, opPackageName); if (type != NULL) { typeStr = env->GetStringUTFChars(type, NULL); if (typeStr == NULL) { // Out of memory lStatus = NO_MEMORY; jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); goto setup_exit; } } if (uuid != NULL) { uuidStr = env->GetStringUTFChars(uuid, NULL); if (uuidStr == NULL) { // Out of memory lStatus = NO_MEMORY; jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); goto setup_exit; } } if (typeStr == NULL && uuidStr == NULL) { lStatus = BAD_VALUE; goto setup_exit; } nId = reinterpret_cast<jint *>(env->GetPrimitiveArrayCritical(jId, NULL)); if (nId == NULL) { ALOGE("setup: Error retrieving id pointer"); lStatus = BAD_VALUE; goto setup_exit; } // create the native SourceDefaultEffect. audio_unique_id_t id; lStatus = AudioEffect::addSourceDefaultEffect(typeStr, String16(opPackageNameStr.c_str()), uuidStr, priority, static_cast<audio_source_t>(source), &id); if (lStatus != NO_ERROR) { ALOGE("setup: Error adding SourceDefaultEffect"); goto setup_exit; } nId[0] = static_cast<jint>(id); setup_exit: // Final cleanup and return. if (nId != NULL) { env->ReleasePrimitiveArrayCritical(jId, nId, 0); nId = NULL; } if (uuidStr != NULL) { env->ReleaseStringUTFChars(uuid, uuidStr); uuidStr = NULL; } if (typeStr != NULL) { env->ReleaseStringUTFChars(type, typeStr); typeStr = NULL; } return AudioEffectJni::translateNativeErrorToJava(lStatus); } static void android_media_SourceDefaultEffect_native_release(JNIEnv */*env*/, jobject /*thiz*/, jint id) { status_t lStatus = AudioEffect::removeSourceDefaultEffect(id); if (lStatus != NO_ERROR) { ALOGW("Error releasing SourceDefaultEffect: %d", lStatus); } } // ---------------------------------------------------------------------------- // Dalvik VM type signatures static const JNINativeMethod gMethods[] = { {"native_setup", "(Ljava/lang/String;Ljava/lang/String;IILjava/lang/String;[I)I", (void *)android_media_SourceDefaultEffect_native_setup}, {"native_release", "(I)V", (void *)android_media_SourceDefaultEffect_native_release}, }; // ---------------------------------------------------------------------------- int register_android_media_SourceDefaultEffect(JNIEnv *env) { return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); }