Loading core/jni/android_media_AudioSystem.cpp +42 −12 Original line number Diff line number Diff line Loading @@ -142,7 +142,14 @@ static struct { static const char* const kEventHandlerClassPathName = "android/media/AudioPortEventHandler"; static jmethodID gPostEventFromNative; static struct { jfieldID mJniCallback; } gEventHandlerFields; static struct { jmethodID postEventFromNative; } gAudioPortEventHandlerMethods; static Mutex gLock; enum AudioError { kAudioStatusOk = 0, Loading Loading @@ -173,14 +180,14 @@ public: private: void sendEvent(int event); jclass mClass; // Reference to AudioPortEventHandlerDelegate class jobject mObject; // Weak ref to AudioPortEventHandlerDelegate Java object to call on jclass mClass; // Reference to AudioPortEventHandler class jobject mObject; // Weak ref to AudioPortEventHandler Java object to call on }; JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz) { // Hold onto the SoundTriggerModule class for use in calling the static method // Hold onto the AudioPortEventHandler class for use in calling the static method // that posts events to the application thread. jclass clazz = env->GetObjectClass(thiz); if (clazz == NULL) { Loading @@ -189,7 +196,7 @@ JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject we } mClass = (jclass)env->NewGlobalRef(clazz); // We use a weak reference so the SoundTriggerModule object can be garbage collected. // We use a weak reference so the AudioPortEventHandler object can be garbage collected. // The reference is only used as a proxy for callbacks. mObject = env->NewGlobalRef(weak_thiz); } Loading @@ -211,7 +218,7 @@ void JNIAudioPortCallback::sendEvent(int event) if (env == NULL) { return; } env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject, env->CallStaticVoidMethod(mClass, gAudioPortEventHandlerMethods.postEventFromNative, mObject, event, 0, 0, NULL); if (env->ExceptionCheck()) { ALOGW("An exception occurred while notifying an event."); Loading @@ -234,6 +241,23 @@ void JNIAudioPortCallback::onServiceDied() sendEvent(AUDIOPORT_EVENT_SERVICE_DIED); } static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env, jobject thiz, const sp<JNIAudioPortCallback>& callback) { Mutex::Autolock l(gLock); sp<JNIAudioPortCallback> old = (JNIAudioPortCallback*)env->GetLongField(thiz, gEventHandlerFields.mJniCallback); if (callback.get()) { callback->incStrong((void*)setJniCallback); } if (old != 0) { old->decStrong((void*)setJniCallback); } env->SetLongField(thiz, gEventHandlerFields.mJniCallback, (jlong)callback.get()); return old; } static int check_AudioSystem_Command(status_t status) { switch (status) { Loading Loading @@ -1355,7 +1379,9 @@ android_media_AudioSystem_eventHandlerSetup(JNIEnv *env, jobject thiz, jobject w sp<JNIAudioPortCallback> callback = new JNIAudioPortCallback(env, thiz, weak_this); AudioSystem::setAudioPortCallback(callback); if (AudioSystem::addAudioPortCallback(callback) == NO_ERROR) { setJniCallback(env, thiz, callback); } } static void Loading @@ -1363,9 +1389,11 @@ android_media_AudioSystem_eventHandlerFinalize(JNIEnv *env, jobject thiz) { ALOGV("eventHandlerFinalize"); sp<JNIAudioPortCallback> callback; sp<JNIAudioPortCallback> callback = setJniCallback(env, thiz, 0); AudioSystem::setAudioPortCallback(callback); if (callback != 0) { AudioSystem::removeAudioPortCallback(callback); } } static jint Loading Loading @@ -1636,9 +1664,11 @@ int register_android_media_AudioSystem(JNIEnv *env) "Landroid/media/AudioHandle;"); jclass eventHandlerClass = FindClassOrDie(env, kEventHandlerClassPathName); gPostEventFromNative = GetStaticMethodIDOrDie(env, eventHandlerClass, "postEventFromNative", gAudioPortEventHandlerMethods.postEventFromNative = GetStaticMethodIDOrDie( env, eventHandlerClass, "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V"); gEventHandlerFields.mJniCallback = GetFieldIDOrDie(env, eventHandlerClass, "mJniCallback", "J"); jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix"); gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass); Loading media/java/android/media/AudioPortEventHandler.java +11 −3 Original line number Diff line number Diff line Loading @@ -40,6 +40,12 @@ class AudioPortEventHandler { private static final int AUDIOPORT_EVENT_SERVICE_DIED = 3; private static final int AUDIOPORT_EVENT_NEW_LISTENER = 4; /** * Accessed by native methods: JNI Callback context. */ @SuppressWarnings("unused") private long mJniCallback; void init() { synchronized (this) { if (mHandler != null) { Loading @@ -63,9 +69,6 @@ class AudioPortEventHandler { listeners = mListeners; } } if (listeners.isEmpty()) { return; } // reset audio port cache if the event corresponds to a change coming // from audio policy service or if mediaserver process died. if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED || Loading @@ -73,6 +76,11 @@ class AudioPortEventHandler { msg.what == AUDIOPORT_EVENT_SERVICE_DIED) { AudioManager.resetAudioPortGeneration(); } if (listeners.isEmpty()) { return; } ArrayList<AudioPort> ports = new ArrayList<AudioPort>(); ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>(); if (msg.what != AUDIOPORT_EVENT_SERVICE_DIED) { Loading Loading
core/jni/android_media_AudioSystem.cpp +42 −12 Original line number Diff line number Diff line Loading @@ -142,7 +142,14 @@ static struct { static const char* const kEventHandlerClassPathName = "android/media/AudioPortEventHandler"; static jmethodID gPostEventFromNative; static struct { jfieldID mJniCallback; } gEventHandlerFields; static struct { jmethodID postEventFromNative; } gAudioPortEventHandlerMethods; static Mutex gLock; enum AudioError { kAudioStatusOk = 0, Loading Loading @@ -173,14 +180,14 @@ public: private: void sendEvent(int event); jclass mClass; // Reference to AudioPortEventHandlerDelegate class jobject mObject; // Weak ref to AudioPortEventHandlerDelegate Java object to call on jclass mClass; // Reference to AudioPortEventHandler class jobject mObject; // Weak ref to AudioPortEventHandler Java object to call on }; JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz) { // Hold onto the SoundTriggerModule class for use in calling the static method // Hold onto the AudioPortEventHandler class for use in calling the static method // that posts events to the application thread. jclass clazz = env->GetObjectClass(thiz); if (clazz == NULL) { Loading @@ -189,7 +196,7 @@ JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject we } mClass = (jclass)env->NewGlobalRef(clazz); // We use a weak reference so the SoundTriggerModule object can be garbage collected. // We use a weak reference so the AudioPortEventHandler object can be garbage collected. // The reference is only used as a proxy for callbacks. mObject = env->NewGlobalRef(weak_thiz); } Loading @@ -211,7 +218,7 @@ void JNIAudioPortCallback::sendEvent(int event) if (env == NULL) { return; } env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject, env->CallStaticVoidMethod(mClass, gAudioPortEventHandlerMethods.postEventFromNative, mObject, event, 0, 0, NULL); if (env->ExceptionCheck()) { ALOGW("An exception occurred while notifying an event."); Loading @@ -234,6 +241,23 @@ void JNIAudioPortCallback::onServiceDied() sendEvent(AUDIOPORT_EVENT_SERVICE_DIED); } static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env, jobject thiz, const sp<JNIAudioPortCallback>& callback) { Mutex::Autolock l(gLock); sp<JNIAudioPortCallback> old = (JNIAudioPortCallback*)env->GetLongField(thiz, gEventHandlerFields.mJniCallback); if (callback.get()) { callback->incStrong((void*)setJniCallback); } if (old != 0) { old->decStrong((void*)setJniCallback); } env->SetLongField(thiz, gEventHandlerFields.mJniCallback, (jlong)callback.get()); return old; } static int check_AudioSystem_Command(status_t status) { switch (status) { Loading Loading @@ -1355,7 +1379,9 @@ android_media_AudioSystem_eventHandlerSetup(JNIEnv *env, jobject thiz, jobject w sp<JNIAudioPortCallback> callback = new JNIAudioPortCallback(env, thiz, weak_this); AudioSystem::setAudioPortCallback(callback); if (AudioSystem::addAudioPortCallback(callback) == NO_ERROR) { setJniCallback(env, thiz, callback); } } static void Loading @@ -1363,9 +1389,11 @@ android_media_AudioSystem_eventHandlerFinalize(JNIEnv *env, jobject thiz) { ALOGV("eventHandlerFinalize"); sp<JNIAudioPortCallback> callback; sp<JNIAudioPortCallback> callback = setJniCallback(env, thiz, 0); AudioSystem::setAudioPortCallback(callback); if (callback != 0) { AudioSystem::removeAudioPortCallback(callback); } } static jint Loading Loading @@ -1636,9 +1664,11 @@ int register_android_media_AudioSystem(JNIEnv *env) "Landroid/media/AudioHandle;"); jclass eventHandlerClass = FindClassOrDie(env, kEventHandlerClassPathName); gPostEventFromNative = GetStaticMethodIDOrDie(env, eventHandlerClass, "postEventFromNative", gAudioPortEventHandlerMethods.postEventFromNative = GetStaticMethodIDOrDie( env, eventHandlerClass, "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V"); gEventHandlerFields.mJniCallback = GetFieldIDOrDie(env, eventHandlerClass, "mJniCallback", "J"); jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix"); gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass); Loading
media/java/android/media/AudioPortEventHandler.java +11 −3 Original line number Diff line number Diff line Loading @@ -40,6 +40,12 @@ class AudioPortEventHandler { private static final int AUDIOPORT_EVENT_SERVICE_DIED = 3; private static final int AUDIOPORT_EVENT_NEW_LISTENER = 4; /** * Accessed by native methods: JNI Callback context. */ @SuppressWarnings("unused") private long mJniCallback; void init() { synchronized (this) { if (mHandler != null) { Loading @@ -63,9 +69,6 @@ class AudioPortEventHandler { listeners = mListeners; } } if (listeners.isEmpty()) { return; } // reset audio port cache if the event corresponds to a change coming // from audio policy service or if mediaserver process died. if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED || Loading @@ -73,6 +76,11 @@ class AudioPortEventHandler { msg.what == AUDIOPORT_EVENT_SERVICE_DIED) { AudioManager.resetAudioPortGeneration(); } if (listeners.isEmpty()) { return; } ArrayList<AudioPort> ports = new ArrayList<AudioPort>(); ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>(); if (msg.what != AUDIOPORT_EVENT_SERVICE_DIED) { Loading