diff options
author | Roman Birg <roman@cyngn.com> | 2016-06-15 12:07:28 -0700 |
---|---|---|
committer | Roman Birg <roman@cyngn.com> | 2016-06-25 11:06:06 -0700 |
commit | 4924f5960eeb7c8333d2050b8196e96355055c07 (patch) | |
tree | c5b567025ec504efb5e7d051edc012a4c164f6a4 | |
parent | 8fed12de2c471c04c11d6a4b5f65bc06f1aef8a0 (diff) | |
download | android_packages_apps_Bluetooth-4924f5960eeb7c8333d2050b8196e96355055c07.tar.gz android_packages_apps_Bluetooth-4924f5960eeb7c8333d2050b8196e96355055c07.tar.bz2 android_packages_apps_Bluetooth-4924f5960eeb7c8333d2050b8196e96355055c07.zip |
Revert "Revert "Ensure synchronized access of JNI callback object""
This is a valid fix and we shouldn't need to revert it.
This reverts commit 9792f9638a9d3f7dc84cb80182fa188d639d4ae5.
Change-Id: I4c41ec98addcfc1630f054e01024bfecf12c1754
-rw-r--r-- | jni/com_android_bluetooth_a2dp.cpp | 81 |
1 files changed, 53 insertions, 28 deletions
diff --git a/jni/com_android_bluetooth_a2dp.cpp b/jni/com_android_bluetooth_a2dp.cpp index df8fe9837..565cd99a9 100644 --- a/jni/com_android_bluetooth_a2dp.cpp +++ b/jni/com_android_bluetooth_a2dp.cpp @@ -27,6 +27,7 @@ #include "android_runtime/AndroidRuntime.h" #include <string.h> +#include <pthread.h> namespace android { static jmethodID method_onConnectionStateChanged; @@ -39,6 +40,8 @@ static const btav_interface_t *sBluetoothA2dpInterface = NULL; static jobject mCallbacksObj = NULL; static JNIEnv *sCallbackEnv = NULL; +static pthread_mutex_t mMutex = PTHREAD_MUTEX_INITIALIZER; + static bool checkCallbackThread() { // Always fetch the latest callbackEnv from AdapterService. // Caching this could cause this sCallbackEnv to go out-of-sync @@ -58,10 +61,6 @@ static void bta2dp_connection_state_callback(btav_connection_state_t state, bt_b ALOGI("%s", __FUNCTION__); - if (mCallbacksObj == NULL) { - ALOGE("Callbacks Obj is no more valid: '%s", __FUNCTION__); - return; - } if (!checkCallbackThread()) { \ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \ return; \ @@ -75,8 +74,16 @@ static void bta2dp_connection_state_callback(btav_connection_state_t state, bt_b } sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); - sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, (jint) state, - addr); + + pthread_mutex_lock(&mMutex); + if (mCallbacksObj != NULL) { + sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, + (jint) state, addr); + } else { + ALOGE("Callbacks Obj is no more valid: '%s", __FUNCTION__); + } + pthread_mutex_unlock(&mMutex); + checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); sCallbackEnv->DeleteLocalRef(addr); } @@ -86,10 +93,6 @@ static void bta2dp_audio_state_callback(btav_audio_state_t state, bt_bdaddr_t* b ALOGI("%s", __FUNCTION__); - if (mCallbacksObj == NULL) { - ALOGE("Callbacks Obj is no more valid: '%s", __FUNCTION__); - return; - } if (!checkCallbackThread()) { \ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \ return; \ @@ -102,8 +105,16 @@ static void bta2dp_audio_state_callback(btav_audio_state_t state, bt_bdaddr_t* b } sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); - sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, (jint) state, - addr); + + pthread_mutex_lock(&mMutex); + if (mCallbacksObj != NULL) { + sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, + (jint) state, addr); + } else { + ALOGE("Callbacks Obj is no more valid: '%s", __FUNCTION__); + } + pthread_mutex_unlock(&mMutex); + checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); sCallbackEnv->DeleteLocalRef(addr); } @@ -113,10 +124,6 @@ static void bta2dp_connection_priority_callback(bt_bdaddr_t* bd_addr) { ALOGI("%s", __FUNCTION__); - if (mCallbacksObj == NULL) { - ALOGE("Callbacks Obj is no more valid: '%s", __FUNCTION__); - return; - } if (!checkCallbackThread()) { \ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \ return; \ @@ -129,7 +136,16 @@ static void bta2dp_connection_priority_callback(bt_bdaddr_t* bd_addr) { } sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); - sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCheckConnectionPriority, addr); + + pthread_mutex_lock(&mMutex); + if (mCallbacksObj != NULL) { + sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCheckConnectionPriority, + addr); + } else { + ALOGE("Callbacks Obj is no more valid: '%s", __FUNCTION__); + } + pthread_mutex_unlock(&mMutex); + checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); sCallbackEnv->DeleteLocalRef(addr); } @@ -138,16 +154,20 @@ static void bta2dp_multicast_enabled_callback(int state) { ALOGI("%s", __FUNCTION__); - if (mCallbacksObj == NULL) { - ALOGE("Callbacks Obj is no more valid: '%s", __FUNCTION__); - return; - } if (!checkCallbackThread()) { \ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \ return; \ } - sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMulticastStateChanged, state); + pthread_mutex_lock(&mMutex); + if (mCallbacksObj != NULL) { + sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMulticastStateChanged, + state); + } else { + ALOGE("Callbacks Obj is no more valid: '%s", __FUNCTION__); + } + pthread_mutex_unlock(&mMutex); + checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); } @@ -218,29 +238,32 @@ static void initNative(JNIEnv *env, jobject object, jint maxA2dpConnections, sBluetoothA2dpInterface = NULL; } - if (mCallbacksObj != NULL) { - ALOGW("Cleaning up A2DP callback object"); - env->DeleteGlobalRef(mCallbacksObj); - mCallbacksObj = NULL; - } - if ( (sBluetoothA2dpInterface = (btav_interface_t *) btInf->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID)) == NULL) { ALOGE("Failed to get Bluetooth A2DP Interface"); return; } + pthread_mutex_lock(&mMutex); + if (mCallbacksObj != NULL) { + ALOGW("Cleaning up A2DP callback object"); + env->DeleteGlobalRef(mCallbacksObj); + mCallbacksObj = NULL; + } mCallbacksObj = env->NewGlobalRef(object); + pthread_mutex_unlock(&mMutex); if ( (status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks, maxA2dpConnections, multiCastState)) != BT_STATUS_SUCCESS) { ALOGE("Failed to initialize Bluetooth A2DP, status: %d", status); sBluetoothA2dpInterface = NULL; + pthread_mutex_lock(&mMutex); if (mCallbacksObj != NULL) { ALOGW("Clean up A2DP callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } + pthread_mutex_unlock(&mMutex); return; } @@ -260,10 +283,12 @@ static void cleanupNative(JNIEnv *env, jobject object) { sBluetoothA2dpInterface = NULL; } + pthread_mutex_lock(&mMutex); if (mCallbacksObj != NULL) { env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } + pthread_mutex_unlock(&mMutex); } static jboolean connectA2dpNative(JNIEnv *env, jobject object, jbyteArray address) { |