Loading core/jni/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ LOCAL_SRC_FILES:= \ android_media_AudioRecord.cpp \ android_media_AudioSystem.cpp \ android_media_AudioTrack.cpp \ android_media_DeviceCallback.cpp \ android_media_JetPlayer.cpp \ android_media_RemoteDisplay.cpp \ android_media_ToneGenerator.cpp \ Loading core/jni/android_media_AudioRecord.cpp +92 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "android_media_AudioFormat.h" #include "android_media_AudioErrors.h" #include "android_media_DeviceCallback.h" // ---------------------------------------------------------------------------- Loading @@ -44,6 +45,7 @@ struct audio_record_fields_t { jmethodID postNativeEventInJava; //... event post callback method jfieldID nativeRecorderInJavaObj; // provides access to the C++ AudioRecord object jfieldID nativeCallbackCookie; // provides access to the AudioRecord callback data jfieldID nativeDeviceCallback; // provides access to the JNIDeviceCallback instance }; struct audio_attributes_fields_t { jfieldID fieldRecSource; // AudioAttributes.mSource Loading Loading @@ -120,6 +122,33 @@ static void recorderCallback(int event, void* user, void *info) { } } static sp<JNIDeviceCallback> getJniDeviceCallback(JNIEnv* env, jobject thiz) { Mutex::Autolock l(sLock); JNIDeviceCallback* const cb = (JNIDeviceCallback*)env->GetLongField(thiz, javaAudioRecordFields.nativeDeviceCallback); return sp<JNIDeviceCallback>(cb); } static sp<JNIDeviceCallback> setJniDeviceCallback(JNIEnv* env, jobject thiz, const sp<JNIDeviceCallback>& cb) { Mutex::Autolock l(sLock); sp<JNIDeviceCallback> old = (JNIDeviceCallback*)env->GetLongField(thiz, javaAudioRecordFields.nativeDeviceCallback); if (cb.get()) { cb->incStrong((void*)setJniDeviceCallback); } if (old != 0) { old->decStrong((void*)setJniDeviceCallback); } env->SetLongField(thiz, javaAudioRecordFields.nativeDeviceCallback, (jlong)cb.get()); return old; } // ---------------------------------------------------------------------------- static sp<AudioRecord> getAudioRecord(JNIEnv* env, jobject thiz) { Loading Loading @@ -593,9 +622,63 @@ static jboolean android_media_AudioRecord_setInputDevice( JNIEnv *env, jobject thiz, jint device_id) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return 0; } return lpRecorder->setInputDevice(device_id) == NO_ERROR; } static jint android_media_AudioRecord_getRoutedDeviceId( JNIEnv *env, jobject thiz) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return 0; } return (jint)lpRecorder->getRoutedDeviceId(); } static void android_media_AudioRecord_enableDeviceCallback( JNIEnv *env, jobject thiz) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return; } sp<JNIDeviceCallback> cb = getJniDeviceCallback(env, thiz); if (cb != 0) { return; } audiorecord_callback_cookie *cookie = (audiorecord_callback_cookie *)env->GetLongField(thiz, javaAudioRecordFields.nativeCallbackCookie); if (cookie == NULL) { return; } cb = new JNIDeviceCallback(env, thiz, cookie->audioRecord_ref, javaAudioRecordFields.postNativeEventInJava); status_t status = lpRecorder->addAudioDeviceCallback(cb); if (status == NO_ERROR) { setJniDeviceCallback(env, thiz, cb); } } static void android_media_AudioRecord_disableDeviceCallback( JNIEnv *env, jobject thiz) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return; } sp<JNIDeviceCallback> cb = setJniDeviceCallback(env, thiz, 0); if (cb != 0) { lpRecorder->removeAudioDeviceCallback(cb); } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { Loading Loading @@ -628,12 +711,17 @@ static JNINativeMethod gMethods[] = { {"native_get_min_buff_size", "(III)I", (void *)android_media_AudioRecord_get_min_buff_size}, {"native_setInputDevice", "(I)Z", (void *)android_media_AudioRecord_setInputDevice}, {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioRecord_getRoutedDeviceId}, {"native_enableDeviceCallback", "()V", (void *)android_media_AudioRecord_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", (void *)android_media_AudioRecord_disableDeviceCallback}, }; // field names found in android/media/AudioRecord.java #define JAVA_POSTEVENT_CALLBACK_NAME "postEventFromNative" #define JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME "mNativeRecorderInJavaObj" #define JAVA_NATIVECALLBACKINFO_FIELD_NAME "mNativeCallbackCookie" #define JAVA_NATIVEDEVICECALLBACK_FIELD_NAME "mNativeDeviceCallback" // ---------------------------------------------------------------------------- int register_android_media_AudioRecord(JNIEnv *env) Loading @@ -641,6 +729,7 @@ int register_android_media_AudioRecord(JNIEnv *env) javaAudioRecordFields.postNativeEventInJava = NULL; javaAudioRecordFields.nativeRecorderInJavaObj = NULL; javaAudioRecordFields.nativeCallbackCookie = NULL; javaAudioRecordFields.nativeDeviceCallback = NULL; // Get the AudioRecord class Loading @@ -658,6 +747,9 @@ int register_android_media_AudioRecord(JNIEnv *env) javaAudioRecordFields.nativeCallbackCookie = GetFieldIDOrDie(env, audioRecordClass, JAVA_NATIVECALLBACKINFO_FIELD_NAME, "J"); javaAudioRecordFields.nativeDeviceCallback = GetFieldIDOrDie(env, audioRecordClass, JAVA_NATIVEDEVICECALLBACK_FIELD_NAME, "J"); // Get the AudioAttributes class and fields jclass audioAttrClass = FindClassOrDie(env, kAudioAttributesClassPathName); javaAudioAttrFields.fieldRecSource = GetFieldIDOrDie(env, audioAttrClass, "mSource", "I"); Loading core/jni/android_media_AudioSystem.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -937,7 +937,8 @@ static jint convertAudioPortFromNative(JNIEnv *env, } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) { ALOGV("convertAudioPortFromNative is a mix"); *jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor, jHandle, nAudioPort->role, jDeviceName, jHandle, nAudioPort->ext.mix.handle, nAudioPort->role, jDeviceName, jSamplingRates, jChannelMasks, jFormats, jGains); } else { Loading Loading @@ -1670,7 +1671,7 @@ int register_android_media_AudioSystem(JNIEnv *env) jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort"); gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass); gAudioMixPortCstor = GetMethodIDOrDie(env, audioMixPortClass, "<init>", "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[Landroid/media/AudioGain;)V"); "(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[Landroid/media/AudioGain;)V"); jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain"); gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass); Loading core/jni/android_media_AudioTrack.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include "android_media_AudioFormat.h" #include "android_media_AudioErrors.h" #include "android_media_PlaybackSettings.h" #include "android_media_DeviceCallback.h" // ---------------------------------------------------------------------------- Loading Loading @@ -79,6 +80,7 @@ class AudioTrackJniStorage { sp<MemoryHeapBase> mMemHeap; sp<MemoryBase> mMemBase; audiotrack_callback_cookie mCallbackData; sp<JNIDeviceCallback> mDeviceCallback; AudioTrackJniStorage() { mCallbackData.audioTrack_class = 0; Loading Loading @@ -977,6 +979,51 @@ static jboolean android_media_AudioTrack_setOutputDevice( return lpTrack->setOutputDevice(device_id) == NO_ERROR; } static jint android_media_AudioTrack_getRoutedDeviceId( JNIEnv *env, jobject thiz) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { return 0; } return (jint)lpTrack->getRoutedDeviceId(); } static void android_media_AudioTrack_enableDeviceCallback( JNIEnv *env, jobject thiz) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { return; } AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField( thiz, javaAudioTrackFields.jniData); if (pJniStorage == NULL || pJniStorage->mDeviceCallback != 0) { return; } pJniStorage->mDeviceCallback = new JNIDeviceCallback(env, thiz, pJniStorage->mCallbackData.audioTrack_ref, javaAudioTrackFields.postNativeEventInJava); lpTrack->addAudioDeviceCallback(pJniStorage->mDeviceCallback); } static void android_media_AudioTrack_disableDeviceCallback( JNIEnv *env, jobject thiz) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { return; } AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField( thiz, javaAudioTrackFields.jniData); if (pJniStorage == NULL || pJniStorage->mDeviceCallback == 0) { return; } lpTrack->removeAudioDeviceCallback(pJniStorage->mDeviceCallback); pJniStorage->mDeviceCallback.clear(); } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { Loading Loading @@ -1030,6 +1077,9 @@ static JNINativeMethod gMethods[] = { "(I)I", (void *)android_media_AudioTrack_attachAuxEffect}, {"native_setOutputDevice", "(I)Z", (void *)android_media_AudioTrack_setOutputDevice}, {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioTrack_getRoutedDeviceId}, {"native_enableDeviceCallback", "()V", (void *)android_media_AudioTrack_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", (void *)android_media_AudioTrack_disableDeviceCallback}, }; Loading core/jni/android_media_DeviceCallback.cpp 0 → 100644 +82 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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 "AudioDeviceCallback-JNI" #include <utils/Log.h> #include <JNIHelp.h> #include <JniConstants.h> #include "core_jni_helpers.h" #include <media/AudioSystem.h> #include "android_media_DeviceCallback.h" // ---------------------------------------------------------------------------- using namespace android; JNIDeviceCallback::JNIDeviceCallback(JNIEnv* env, jobject thiz, jobject weak_thiz, jmethodID postEventFromNative) { // Hold onto the AudioTrack/AudioRecord class for use in calling the static method // that posts events to the application thread. jclass clazz = env->GetObjectClass(thiz); if (clazz == NULL) { return; } mClass = (jclass)env->NewGlobalRef(clazz); // We use a weak reference so the AudioTrack/AudioRecord object can be garbage collected. // The reference is only used as a proxy for callbacks. mObject = env->NewGlobalRef(weak_thiz); mPostEventFromNative = postEventFromNative; } JNIDeviceCallback::~JNIDeviceCallback() { // remove global references JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } env->DeleteGlobalRef(mObject); env->DeleteGlobalRef(mClass); } void JNIDeviceCallback::onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId) { JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } ALOGV("%s audioIo %d deviceId %d", __FUNCTION__, audioIo, deviceId); env->CallStaticVoidMethod(mClass, mPostEventFromNative, mObject, AUDIO_NATIVE_EVENT_ROUTING_CHANGE, deviceId, 0, NULL); if (env->ExceptionCheck()) { ALOGW("An exception occurred while notifying an event."); env->ExceptionClear(); } } Loading
core/jni/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ LOCAL_SRC_FILES:= \ android_media_AudioRecord.cpp \ android_media_AudioSystem.cpp \ android_media_AudioTrack.cpp \ android_media_DeviceCallback.cpp \ android_media_JetPlayer.cpp \ android_media_RemoteDisplay.cpp \ android_media_ToneGenerator.cpp \ Loading
core/jni/android_media_AudioRecord.cpp +92 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "android_media_AudioFormat.h" #include "android_media_AudioErrors.h" #include "android_media_DeviceCallback.h" // ---------------------------------------------------------------------------- Loading @@ -44,6 +45,7 @@ struct audio_record_fields_t { jmethodID postNativeEventInJava; //... event post callback method jfieldID nativeRecorderInJavaObj; // provides access to the C++ AudioRecord object jfieldID nativeCallbackCookie; // provides access to the AudioRecord callback data jfieldID nativeDeviceCallback; // provides access to the JNIDeviceCallback instance }; struct audio_attributes_fields_t { jfieldID fieldRecSource; // AudioAttributes.mSource Loading Loading @@ -120,6 +122,33 @@ static void recorderCallback(int event, void* user, void *info) { } } static sp<JNIDeviceCallback> getJniDeviceCallback(JNIEnv* env, jobject thiz) { Mutex::Autolock l(sLock); JNIDeviceCallback* const cb = (JNIDeviceCallback*)env->GetLongField(thiz, javaAudioRecordFields.nativeDeviceCallback); return sp<JNIDeviceCallback>(cb); } static sp<JNIDeviceCallback> setJniDeviceCallback(JNIEnv* env, jobject thiz, const sp<JNIDeviceCallback>& cb) { Mutex::Autolock l(sLock); sp<JNIDeviceCallback> old = (JNIDeviceCallback*)env->GetLongField(thiz, javaAudioRecordFields.nativeDeviceCallback); if (cb.get()) { cb->incStrong((void*)setJniDeviceCallback); } if (old != 0) { old->decStrong((void*)setJniDeviceCallback); } env->SetLongField(thiz, javaAudioRecordFields.nativeDeviceCallback, (jlong)cb.get()); return old; } // ---------------------------------------------------------------------------- static sp<AudioRecord> getAudioRecord(JNIEnv* env, jobject thiz) { Loading Loading @@ -593,9 +622,63 @@ static jboolean android_media_AudioRecord_setInputDevice( JNIEnv *env, jobject thiz, jint device_id) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return 0; } return lpRecorder->setInputDevice(device_id) == NO_ERROR; } static jint android_media_AudioRecord_getRoutedDeviceId( JNIEnv *env, jobject thiz) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return 0; } return (jint)lpRecorder->getRoutedDeviceId(); } static void android_media_AudioRecord_enableDeviceCallback( JNIEnv *env, jobject thiz) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return; } sp<JNIDeviceCallback> cb = getJniDeviceCallback(env, thiz); if (cb != 0) { return; } audiorecord_callback_cookie *cookie = (audiorecord_callback_cookie *)env->GetLongField(thiz, javaAudioRecordFields.nativeCallbackCookie); if (cookie == NULL) { return; } cb = new JNIDeviceCallback(env, thiz, cookie->audioRecord_ref, javaAudioRecordFields.postNativeEventInJava); status_t status = lpRecorder->addAudioDeviceCallback(cb); if (status == NO_ERROR) { setJniDeviceCallback(env, thiz, cb); } } static void android_media_AudioRecord_disableDeviceCallback( JNIEnv *env, jobject thiz) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return; } sp<JNIDeviceCallback> cb = setJniDeviceCallback(env, thiz, 0); if (cb != 0) { lpRecorder->removeAudioDeviceCallback(cb); } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { Loading Loading @@ -628,12 +711,17 @@ static JNINativeMethod gMethods[] = { {"native_get_min_buff_size", "(III)I", (void *)android_media_AudioRecord_get_min_buff_size}, {"native_setInputDevice", "(I)Z", (void *)android_media_AudioRecord_setInputDevice}, {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioRecord_getRoutedDeviceId}, {"native_enableDeviceCallback", "()V", (void *)android_media_AudioRecord_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", (void *)android_media_AudioRecord_disableDeviceCallback}, }; // field names found in android/media/AudioRecord.java #define JAVA_POSTEVENT_CALLBACK_NAME "postEventFromNative" #define JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME "mNativeRecorderInJavaObj" #define JAVA_NATIVECALLBACKINFO_FIELD_NAME "mNativeCallbackCookie" #define JAVA_NATIVEDEVICECALLBACK_FIELD_NAME "mNativeDeviceCallback" // ---------------------------------------------------------------------------- int register_android_media_AudioRecord(JNIEnv *env) Loading @@ -641,6 +729,7 @@ int register_android_media_AudioRecord(JNIEnv *env) javaAudioRecordFields.postNativeEventInJava = NULL; javaAudioRecordFields.nativeRecorderInJavaObj = NULL; javaAudioRecordFields.nativeCallbackCookie = NULL; javaAudioRecordFields.nativeDeviceCallback = NULL; // Get the AudioRecord class Loading @@ -658,6 +747,9 @@ int register_android_media_AudioRecord(JNIEnv *env) javaAudioRecordFields.nativeCallbackCookie = GetFieldIDOrDie(env, audioRecordClass, JAVA_NATIVECALLBACKINFO_FIELD_NAME, "J"); javaAudioRecordFields.nativeDeviceCallback = GetFieldIDOrDie(env, audioRecordClass, JAVA_NATIVEDEVICECALLBACK_FIELD_NAME, "J"); // Get the AudioAttributes class and fields jclass audioAttrClass = FindClassOrDie(env, kAudioAttributesClassPathName); javaAudioAttrFields.fieldRecSource = GetFieldIDOrDie(env, audioAttrClass, "mSource", "I"); Loading
core/jni/android_media_AudioSystem.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -937,7 +937,8 @@ static jint convertAudioPortFromNative(JNIEnv *env, } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) { ALOGV("convertAudioPortFromNative is a mix"); *jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor, jHandle, nAudioPort->role, jDeviceName, jHandle, nAudioPort->ext.mix.handle, nAudioPort->role, jDeviceName, jSamplingRates, jChannelMasks, jFormats, jGains); } else { Loading Loading @@ -1670,7 +1671,7 @@ int register_android_media_AudioSystem(JNIEnv *env) jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort"); gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass); gAudioMixPortCstor = GetMethodIDOrDie(env, audioMixPortClass, "<init>", "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[Landroid/media/AudioGain;)V"); "(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[Landroid/media/AudioGain;)V"); jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain"); gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass); Loading
core/jni/android_media_AudioTrack.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include "android_media_AudioFormat.h" #include "android_media_AudioErrors.h" #include "android_media_PlaybackSettings.h" #include "android_media_DeviceCallback.h" // ---------------------------------------------------------------------------- Loading Loading @@ -79,6 +80,7 @@ class AudioTrackJniStorage { sp<MemoryHeapBase> mMemHeap; sp<MemoryBase> mMemBase; audiotrack_callback_cookie mCallbackData; sp<JNIDeviceCallback> mDeviceCallback; AudioTrackJniStorage() { mCallbackData.audioTrack_class = 0; Loading Loading @@ -977,6 +979,51 @@ static jboolean android_media_AudioTrack_setOutputDevice( return lpTrack->setOutputDevice(device_id) == NO_ERROR; } static jint android_media_AudioTrack_getRoutedDeviceId( JNIEnv *env, jobject thiz) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { return 0; } return (jint)lpTrack->getRoutedDeviceId(); } static void android_media_AudioTrack_enableDeviceCallback( JNIEnv *env, jobject thiz) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { return; } AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField( thiz, javaAudioTrackFields.jniData); if (pJniStorage == NULL || pJniStorage->mDeviceCallback != 0) { return; } pJniStorage->mDeviceCallback = new JNIDeviceCallback(env, thiz, pJniStorage->mCallbackData.audioTrack_ref, javaAudioTrackFields.postNativeEventInJava); lpTrack->addAudioDeviceCallback(pJniStorage->mDeviceCallback); } static void android_media_AudioTrack_disableDeviceCallback( JNIEnv *env, jobject thiz) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { return; } AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField( thiz, javaAudioTrackFields.jniData); if (pJniStorage == NULL || pJniStorage->mDeviceCallback == 0) { return; } lpTrack->removeAudioDeviceCallback(pJniStorage->mDeviceCallback); pJniStorage->mDeviceCallback.clear(); } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { Loading Loading @@ -1030,6 +1077,9 @@ static JNINativeMethod gMethods[] = { "(I)I", (void *)android_media_AudioTrack_attachAuxEffect}, {"native_setOutputDevice", "(I)Z", (void *)android_media_AudioTrack_setOutputDevice}, {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioTrack_getRoutedDeviceId}, {"native_enableDeviceCallback", "()V", (void *)android_media_AudioTrack_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", (void *)android_media_AudioTrack_disableDeviceCallback}, }; Loading
core/jni/android_media_DeviceCallback.cpp 0 → 100644 +82 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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 "AudioDeviceCallback-JNI" #include <utils/Log.h> #include <JNIHelp.h> #include <JniConstants.h> #include "core_jni_helpers.h" #include <media/AudioSystem.h> #include "android_media_DeviceCallback.h" // ---------------------------------------------------------------------------- using namespace android; JNIDeviceCallback::JNIDeviceCallback(JNIEnv* env, jobject thiz, jobject weak_thiz, jmethodID postEventFromNative) { // Hold onto the AudioTrack/AudioRecord class for use in calling the static method // that posts events to the application thread. jclass clazz = env->GetObjectClass(thiz); if (clazz == NULL) { return; } mClass = (jclass)env->NewGlobalRef(clazz); // We use a weak reference so the AudioTrack/AudioRecord object can be garbage collected. // The reference is only used as a proxy for callbacks. mObject = env->NewGlobalRef(weak_thiz); mPostEventFromNative = postEventFromNative; } JNIDeviceCallback::~JNIDeviceCallback() { // remove global references JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } env->DeleteGlobalRef(mObject); env->DeleteGlobalRef(mClass); } void JNIDeviceCallback::onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId) { JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } ALOGV("%s audioIo %d deviceId %d", __FUNCTION__, audioIo, deviceId); env->CallStaticVoidMethod(mClass, mPostEventFromNative, mObject, AUDIO_NATIVE_EVENT_ROUTING_CHANGE, deviceId, 0, NULL); if (env->ExceptionCheck()) { ALOGW("An exception occurred while notifying an event."); env->ExceptionClear(); } }