#include "jni.h"
#include "hardware/hardware.h"
#include "hardware/bluetooth.h"
+#include "utils/Log.h"
+#include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
namespace android {
-void checkAndClearExceptionFromCallback(JNIEnv* env,
- const char* methodName);
+JNIEnv* getCallbackEnv();
-const bt_interface_t* getBluetoothInterface();
+class CallbackEnv {
+public:
+ CallbackEnv(const char *methodName) : mName(methodName) {
+ mCallbackEnv = getCallbackEnv();
+ }
+
+ ~CallbackEnv() {
+ if (mCallbackEnv && mCallbackEnv->ExceptionCheck()) {
+ ALOGE("An exception was thrown by callback '%s'.", mName);
+ LOGE_EX(mCallbackEnv);
+ mCallbackEnv->ExceptionClear();
+ }
+ }
+
+ bool valid() const {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ if (!mCallbackEnv || (mCallbackEnv != env)) {
+ ALOGE("%s: Callback env fail: env: %p, callback: %p", mName, env, mCallbackEnv);
+ return false;
+ }
+ return true;
+ }
+
+ JNIEnv *operator-> () const {
+ return mCallbackEnv;
+ }
+
+ JNIEnv *get() const {
+ return mCallbackEnv;
+ }
+
+private:
+ JNIEnv *mCallbackEnv;
+ const char *mName;
+
+ DISALLOW_COPY_AND_ASSIGN(CallbackEnv);
+};
-JNIEnv* getCallbackEnv();
+const bt_interface_t* getBluetoothInterface();
int register_com_android_bluetooth_hfp(JNIEnv* env);
static const btav_interface_t *sBluetoothA2dpInterface = NULL;
static jobject mCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
-
-static bool checkCallbackThread() {
- // Always fetch the latest callbackEnv from AdapterService.
- // Caching this could cause this sCallbackEnv to go out-of-sync
- // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
- // is received
- //if (sCallbackEnv == NULL) {
- sCallbackEnv = getCallbackEnv();
- //}
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
- return true;
-}
static void bta2dp_connection_state_callback(btav_connection_state_t state, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- ALOGI("%s", __FUNCTION__);
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, (jint) state,
addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void bta2dp_audio_state_callback(btav_audio_state_t state, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- ALOGI("%s", __FUNCTION__);
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, (jint) state,
addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static const btav_interface_t *sBluetoothA2dpInterface = NULL;
static jobject mCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
-
-static bool checkCallbackThread() {
- // Always fetch the latest callbackEnv from AdapterService.
- // Caching this could cause this sCallbackEnv to go out-of-sync
- // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
- // is received
- //if (sCallbackEnv == NULL) {
- sCallbackEnv = getCallbackEnv();
- //}
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
- return true;
-}
static void bta2dp_connection_state_callback(btav_connection_state_t state, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- ALOGI("%s", __FUNCTION__);
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, (jint) state,
addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void bta2dp_audio_state_callback(btav_audio_state_t state, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- ALOGI("%s", __FUNCTION__);
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, (jint) state,
addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void bta2dp_audio_config_callback(bt_bdaddr_t *bd_addr, uint32_t sample_rate, uint8_t channel_count) {
jbyteArray addr;
- ALOGI("%s", __FUNCTION__);
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioConfigChanged, addr, (jint)sample_rate, (jint)channel_count);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
#include <string.h>
-#define CHECK_CALLBACK_ENV()\
-do { \
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __func__); \
- return; \
- } \
-} while (0)
-
-
namespace android {
static jmethodID method_getRcFeatures;
static jmethodID method_getPlayStatus;
static const btrc_interface_t *sBluetoothAvrcpInterface = NULL;
static jobject mCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
/* Function declarations */
static bool copy_item_attributes(JNIEnv *env, jobject object, btrc_folder_items_t *pitem,
static void cleanup_items(btrc_folder_items_t* p_items, int numItems);
-static bool checkCallbackThread() {
- // Always fetch the latest callbackEnv from AdapterService.
- // Caching this could cause this sCallbackEnv to go out-of-sync
- // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
- // is received
- sCallbackEnv = getCallbackEnv();
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
- return true;
-}
-
static void btavrcp_remote_features_callback(bt_bdaddr_t* bd_addr,
btrc_remote_features_t features) {
jbyteArray addr;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Unable to allocate byte array for bd_addr");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
ALOGE("%s: mCallbacksObj is null", __func__);
}
-
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
}
/** Callback for play status request */
static void btavrcp_get_play_status_callback(bt_bdaddr_t* bd_addr) {
- ALOGI("%s", __func__);
jbyteArray addr;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for get_play_status command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
} else {
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
}
jbyteArray addr;
jintArray attrs;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for get_element_attr command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
attrs = (jintArray)sCallbackEnv->NewIntArray(num_attr);
if (!attrs) {
ALOGE("Fail to new jintArray for attrs");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
return;
}
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attrs);
sCallbackEnv->DeleteLocalRef(addr);
}
bt_bdaddr_t *bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV();
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for register_notification command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
}
bt_bdaddr_t *bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for volume_change command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
}
sCallbackEnv->DeleteLocalRef(addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
}
static void btavrcp_passthrough_command_callback(int id, int pressed,
bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for passthrough_command command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
}
bt_bdaddr_t *bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for set_addressed_player command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void btavrcp_set_browsed_player_callback(uint16_t player_id, bt_bdaddr_t *bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for set_browsed_player command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
}
jintArray attr_ids = NULL;
uint32_t *puiAttr = (uint32_t *)p_attr_ids;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for get_folder_items command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
attr_ids = (jintArray)sCallbackEnv->NewIntArray(num_attr);
if (!attr_ids) {
ALOGE("Fail to allocate new jintArray for attrs");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
return;
}
}
if (attr_ids != NULL) sCallbackEnv->DeleteLocalRef(attr_ids);
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
}
jbyteArray addr;
jbyteArray attrs;;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
attrs = sCallbackEnv->NewByteArray(BTRC_UID_SIZE);
if (!attrs) {
ALOGE("Fail to new jintArray for attrs");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for change_path command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attrs);
return;
}
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attrs);
sCallbackEnv->DeleteLocalRef(addr);
}
jintArray attrs;
jbyteArray attr_uid;
- CHECK_CALLBACK_ENV();
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
attr_uid = sCallbackEnv->NewByteArray(BTRC_UID_SIZE);
if (!attr_uid) {
ALOGE("Fail to new jintArray for attr_uid");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for get_item_attr command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attr_uid);
return;
}
attrs = (jintArray)sCallbackEnv->NewIntArray(num_attr);
if (!attrs) {
ALOGE("Fail to new jintArray for attrs");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attr_uid);
sCallbackEnv->DeleteLocalRef(addr);
return;
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attr_uid);
sCallbackEnv->DeleteLocalRef(attrs);
sCallbackEnv->DeleteLocalRef(addr);
jbyteArray addr;
jbyteArray attrs;
- CHECK_CALLBACK_ENV();
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
attrs = sCallbackEnv->NewByteArray(BTRC_UID_SIZE);
if (!attrs) {
ALOGE("%s:Fail to new jByteArray attrs for play_item command", __func__);
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for play_item command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attrs);
return;
}
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attrs);
sCallbackEnv->DeleteLocalRef(addr);
}
jbyteArray addr;
- CHECK_CALLBACK_ENV();
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for get_total_num_items command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
}
jbyteArray addr;
jbyteArray attrs;
- CHECK_CALLBACK_ENV();
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
attrs = sCallbackEnv->NewByteArray(str_len);
if (!attrs) {
ALOGE("Fail to new jintArray for attrs");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for search command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attrs);
return;
}
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attrs);
sCallbackEnv->DeleteLocalRef(addr);
}
jbyteArray attrs;
jbyteArray addr;
- CHECK_CALLBACK_ENV();
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for add_to_play_list command");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
attrs = sCallbackEnv->NewByteArray(BTRC_UID_SIZE);
if (!attrs) {
ALOGE("Fail to new jByteArray for attrs");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(addr);
return;
}
ALOGE("%s: mCallbacksObj is null", __func__);
}
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
sCallbackEnv->DeleteLocalRef(attrs);
sCallbackEnv->DeleteLocalRef(addr);
}
static const btrc_ctrl_interface_t *sBluetoothAvrcpInterface = NULL;
static jobject sCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
-static JNIEnv *sEnv = NULL;
-
-static bool checkCallbackThread() {
- // Always fetch the latest callbackEnv from AdapterService.
- // Caching this could cause this sCallbackEnv to go out-of-sync
- // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
- // is received
- sCallbackEnv = getCallbackEnv();
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
- return true;
-}
static void btavrcp_passthrough_response_callback(bt_bdaddr_t* bd_addr, int id, int pressed) {
jbyteArray addr;
- ALOGI("%s", __func__);
- ALOGI("id: %d, pressed: %d", id, pressed);
+ ALOGI("%s: id: %d, pressed: %d", __func__, id, pressed);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __func__);
- return;
- }
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for passthrough response");
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
return;
}
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handlePassthroughRsp, (jint)id,
(jint)pressed,
addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
-
sCallbackEnv->DeleteLocalRef(addr);
}
static void btavrcp_groupnavigation_response_callback(int id, int pressed) {
- ALOGV("%s", __FUNCTION__);
-
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+ ALOGV("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGroupNavigationRsp, (jint)id,
(jint)pressed);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void btavrcp_connection_state_callback(
bool rc_connect, bool br_connect, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- ALOGV("%s", __FUNCTION__);
- ALOGI("%s conn state rc: %d br: %d", __FUNCTION__, rc_connect, br_connect);
-
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
+ ALOGI("%s: conn state: rc: %d br: %d", __func__, rc_connect, br_connect);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_onConnectionStateChanged,
(jboolean) rc_connect, (jboolean) br_connect, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void btavrcp_get_rcfeatures_callback(bt_bdaddr_t *bd_addr, int features) {
jbyteArray addr;
- ALOGV("%s", __FUNCTION__);
-
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
+ ALOGV("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_getRcFeatures, addr, (jint)features);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
uint8_t accepted) {
jbyteArray addr;
- ALOGV("%s", __FUNCTION__);
-
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
+ ALOGV("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_setplayerappsettingrsp, addr, (jint)accepted);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void btavrcp_playerapplicationsetting_callback(bt_bdaddr_t *bd_addr, uint8_t num_attr,
btrc_player_app_attr_t *app_attrs, uint8_t num_ext_attr,
btrc_player_app_ext_attr_t *ext_attrs) {
- ALOGV("%s", __FUNCTION__);
jbyteArray addr;
jbyteArray playerattribs;
jint arraylen;
int i,k;
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
if(!playerattribs)
{
ALOGE("Fail to new jbyteArray playerattribs ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
return;
}
}
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplayerappsetting, addr,
playerattribs, (jint)arraylen);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
sCallbackEnv->DeleteLocalRef(playerattribs);
}
jbyteArray addr;
jbyteArray playerattribs;
int i, k, arraylen;
- ALOGI("%s", __FUNCTION__);
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if ((!addr)) {
ALOGE("Fail to get new array ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
if(!playerattribs)
{
ALOGE("Fail to new jbyteArray playerattribs ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
return;
}
}
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplayerappsettingchanged, addr,
playerattribs, (jint)arraylen);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
sCallbackEnv->DeleteLocalRef(playerattribs);
}
static void btavrcp_set_abs_vol_cmd_callback(bt_bdaddr_t *bd_addr, uint8_t abs_vol,
uint8_t label) {
-
jbyteArray addr;
- ALOGI("%s", __FUNCTION__);
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if ((!addr)) {
ALOGE("Fail to get new array ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleSetAbsVolume, addr, (jbyte)abs_vol,
(jbyte)label);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void btavrcp_register_notification_absvol_callback(bt_bdaddr_t *bd_addr, uint8_t label) {
jbyteArray addr;
- ALOGI("%s", __FUNCTION__);
-
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if ((!addr)) {
ALOGE("Fail to get new array ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleRegisterNotificationAbsVol, addr,
(jbyte)label);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
jstring str;
jclass strclazz;
jint i;
- ALOGI("%s", __FUNCTION__);
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
- return; \
- }
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if ((!addr)) {
ALOGE("Fail to get new array ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
attribIds = sCallbackEnv->NewIntArray(num_attr);
if(!attribIds) {
ALOGE(" failed to set new array for attribIds");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
return;
}
stringArray = sCallbackEnv->NewObjectArray((jint)num_attr, strclazz, 0);
if(!stringArray) {
ALOGE(" failed to get String array");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
sCallbackEnv->DeleteLocalRef(attribIds);
return;
str = sCallbackEnv->NewStringUTF((char*)(p_attrs[i].text));
if(!str) {
ALOGE(" Unable to get str ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
sCallbackEnv->DeleteLocalRef(attribIds);
sCallbackEnv->DeleteLocalRef(stringArray);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handletrackchanged, addr,
(jbyte)(num_attr), attribIds, stringArray);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
sCallbackEnv->DeleteLocalRef(attribIds);
/* TODO check do we need to delete str seperately or not */
uint32_t song_pos) {
jbyteArray addr;
- ALOGI("%s", __FUNCTION__);
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
- if ((!addr)) {
+ if (!addr) {
ALOGE("Fail to get new array ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
static void btavrcp_play_status_changed_callback(bt_bdaddr_t *bd_addr,
btrc_play_status_t play_status) {
jbyteArray addr;
- ALOGI("%s", __FUNCTION__);
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
- if ((!addr)) {
+ if (!addr) {
ALOGE("Fail to get new array ");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
* BTRC_ITEM_MEDIA, BTRC_ITEM_FOLDER. Here we translate them to their java
* counterparts by calling the java constructor for each of the items.
*/
- ALOGV("%s count %d", __FUNCTION__, count);
-
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+ ALOGV("%s count %d", __func__, count);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
// Inspect if the first element is a folder/item or player listing. They are
// always exclusive.
playerItemArray = sCallbackEnv->NewObjectArray((jint) count, class_AvrcpPlayer, 0);
if (!playerItemArray) {
ALOGE("%s playerItemArray allocation failed.", __FUNCTION__);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
} else {
(jint) count, class_MediaBrowser_MediaItem, 0);
if (!folderItemArray) {
ALOGE("%s folderItemArray is empty.", __FUNCTION__);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
}
ALOGE("%s failed to allocate featureBitArray", __FUNCTION__);
sCallbackEnv->DeleteLocalRef(playerItemArray);
sCallbackEnv->DeleteLocalRef(folderItemArray);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(
}
static void btavrcp_change_path_callback(bt_bdaddr_t *bd_addr, uint8_t count) {
- ALOGI("%s count %d", __FUNCTION__, count);
-
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+ ALOGI("%s count %d", __func__, count);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleChangeFolderRsp, (jint) count);
}
static void btavrcp_set_browsed_player_callback(
bt_bdaddr_t *bd_addr, uint8_t num_items, uint8_t depth) {
- ALOGI("%s items %d depth %d", __FUNCTION__, num_items, depth);
-
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+ ALOGI("%s items %d depth %d", __func__, num_items, depth);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(
sCallbacksObj, method_handleSetBrowsedPlayerRsp, (jint) num_items, (jint) depth);
static void initNative(JNIEnv *env, jobject object) {
const bt_interface_t* btInf;
bt_status_t status;
- sEnv = env;
jclass tmpMediaItem = env->FindClass("android/media/browse/MediaBrowser$MediaItem");
class_MediaBrowser_MediaItem = (jclass) env->NewGlobalRef(tmpMediaItem);
static jobject sJniCallbacksObj;
static jfieldID sJniCallbacksField;
-
const bt_interface_t* getBluetoothInterface() {
return sBluetoothInterface;
}
return callbackEnv;
}
-void checkAndClearExceptionFromCallback(JNIEnv* env,
- const char* methodName) {
- if (env->ExceptionCheck()) {
- ALOGE("An exception was thrown by callback '%s'.", methodName);
- LOGE_EX(env);
- env->ExceptionClear();
- }
-}
-
-static bool checkCallbackThread() {
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (callbackEnv != env || callbackEnv == NULL) {
- ALOGE("Callback env check fail: env: %p, callback: %p", env, callbackEnv);
- return false;
- }
- return true;
-}
-
static void adapter_state_change_callback(bt_state_t status) {
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
- ALOGV("%s: Status is: %d", __FUNCTION__, status);
-
- callbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+ ALOGV("%s: Status is: %d", __func__, status);
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
+ sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status);
}
static int get_properties(int num_properties, bt_property_t *properties, jintArray *types,
jbyteArray val;
jclass mclass;
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
ALOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
return;
}
- val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
+ val = (jbyteArray) sCallbackEnv->NewByteArray(num_properties);
if (val == NULL) {
ALOGE("%s: Error allocating byteArray", __FUNCTION__);
return;
}
- mclass = callbackEnv->GetObjectClass(val);
+ mclass = sCallbackEnv->GetObjectClass(val);
/* (BT) Initialize the jobjectArray and jintArray here itself and send the
initialized array pointers alone to get_properties */
- props = callbackEnv->NewObjectArray(num_properties, mclass,
+ props = sCallbackEnv->NewObjectArray(num_properties, mclass,
NULL);
if (props == NULL) {
ALOGE("%s: Error allocating object Array for properties", __FUNCTION__);
return;
}
- types = (jintArray)callbackEnv->NewIntArray(num_properties);
+ types = (jintArray)sCallbackEnv->NewIntArray(num_properties);
if (types == NULL) {
ALOGE("%s: Error allocating int Array for values", __FUNCTION__);
return;
}
// Delete the reference to val and mclass
- callbackEnv->DeleteLocalRef(mclass);
- callbackEnv->DeleteLocalRef(val);
+ sCallbackEnv->DeleteLocalRef(mclass);
+ sCallbackEnv->DeleteLocalRef(val);
if (get_properties(num_properties, properties, &types, &props) < 0) {
- if (props) callbackEnv->DeleteLocalRef(props);
- if (types) callbackEnv->DeleteLocalRef(types);
+ if (props) sCallbackEnv->DeleteLocalRef(props);
+ if (types) sCallbackEnv->DeleteLocalRef(types);
return;
}
- callbackEnv->CallVoidMethod(sJniCallbacksObj, method_adapterPropertyChangedCallback, types,
+ sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_adapterPropertyChangedCallback, types,
props);
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
- callbackEnv->DeleteLocalRef(props);
- callbackEnv->DeleteLocalRef(types);
- return;
-
+ sCallbackEnv->DeleteLocalRef(props);
+ sCallbackEnv->DeleteLocalRef(types);
}
static void remote_device_properties_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
int num_properties, bt_property_t *properties) {
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
ALOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
return;
}
- callbackEnv->PushLocalFrame(ADDITIONAL_NREFS);
+ sCallbackEnv->PushLocalFrame(ADDITIONAL_NREFS);
jobjectArray props;
jbyteArray addr;
jbyteArray val;
jclass mclass;
- val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
+ val = (jbyteArray) sCallbackEnv->NewByteArray(num_properties);
if (val == NULL) {
ALOGE("%s: Error allocating byteArray", __FUNCTION__);
return;
}
- mclass = callbackEnv->GetObjectClass(val);
+ mclass = sCallbackEnv->GetObjectClass(val);
/* Initialize the jobjectArray and jintArray here itself and send the
initialized array pointers alone to get_properties */
- props = callbackEnv->NewObjectArray(num_properties, mclass,
+ props = sCallbackEnv->NewObjectArray(num_properties, mclass,
NULL);
if (props == NULL) {
ALOGE("%s: Error allocating object Array for properties", __FUNCTION__);
return;
}
- types = (jintArray)callbackEnv->NewIntArray(num_properties);
+ types = (jintArray)sCallbackEnv->NewIntArray(num_properties);
if (types == NULL) {
ALOGE("%s: Error allocating int Array for values", __FUNCTION__);
return;
}
// Delete the reference to val and mclass
- callbackEnv->DeleteLocalRef(mclass);
- callbackEnv->DeleteLocalRef(val);
+ sCallbackEnv->DeleteLocalRef(mclass);
+ sCallbackEnv->DeleteLocalRef(val);
- addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
- if (addr == NULL) goto Fail;
- if (addr) callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ if (addr == NULL) {
+ ALOGE("Error while allocation byte array in %s", __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
if (get_properties(num_properties, properties, &types, &props) < 0) {
- if (props) callbackEnv->DeleteLocalRef(props);
- if (types) callbackEnv->DeleteLocalRef(types);
- callbackEnv->PopLocalFrame(NULL);
+ if (props) sCallbackEnv->DeleteLocalRef(props);
+ if (types) sCallbackEnv->DeleteLocalRef(types);
+ sCallbackEnv->PopLocalFrame(NULL);
return;
}
- callbackEnv->CallVoidMethod(sJniCallbacksObj, method_devicePropertyChangedCallback, addr,
+ sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_devicePropertyChangedCallback, addr,
types, props);
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
- callbackEnv->DeleteLocalRef(props);
- callbackEnv->DeleteLocalRef(types);
- callbackEnv->DeleteLocalRef(addr);
- callbackEnv->PopLocalFrame(NULL);
- return;
-
-Fail:
- ALOGE("Error while allocation byte array in %s", __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(props);
+ sCallbackEnv->DeleteLocalRef(types);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->PopLocalFrame(NULL);
}
static void device_found_callback(int num_properties, bt_property_t *properties) {
jbyteArray addr = NULL;
int addr_index;
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
for (int i = 0; i < num_properties; i++) {
if (properties[i].type == BT_PROPERTY_BDADDR) {
- addr = callbackEnv->NewByteArray(properties[i].len);
+ addr = sCallbackEnv->NewByteArray(properties[i].len);
if (addr) {
- callbackEnv->SetByteArrayRegion(addr, 0, properties[i].len,
+ sCallbackEnv->SetByteArrayRegion(addr, 0, properties[i].len,
(jbyte*)properties[i].val);
addr_index = i;
} else {
remote_device_properties_callback(BT_STATUS_SUCCESS, (bt_bdaddr_t *)properties[addr_index].val,
num_properties, properties);
- callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, addr);
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
- callbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, addr);
+ sCallbackEnv->DeleteLocalRef(addr);
}
static void bond_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
bt_bond_state_t state) {
jbyteArray addr;
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
if (!bd_addr) {
ALOGE("Address is null in %s", __FUNCTION__);
return;
}
- addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (addr == NULL) {
ALOGE("Address allocation failed in %s", __FUNCTION__);
return;
}
- callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
- callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status,
+ sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status,
addr, (jint)state);
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
- callbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(addr);
}
static void acl_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
bt_acl_state_t state)
{
jbyteArray addr;
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+
if (!bd_addr) {
ALOGE("Address is null in %s", __FUNCTION__);
return;
}
- addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (addr == NULL) {
ALOGE("Address allocation failed in %s", __FUNCTION__);
return;
}
- callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
- callbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, (jint) status,
+ sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, (jint) status,
addr, (jint)state);
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
- callbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(addr);
}
static void discovery_state_changed_callback(bt_discovery_state_t state) {
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
ALOGV("%s: DiscoveryState:%d ", __FUNCTION__, state);
- callbackEnv->CallVoidMethod(sJniCallbacksObj, method_discoveryStateChangeCallback,
+ sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_discoveryStateChangeCallback,
(jint)state);
-
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
}
static void pin_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod,
bool min_16_digits) {
jbyteArray addr = NULL;
jbyteArray devname = NULL;
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
if (!bd_addr) {
ALOGE("Address is null in %s", __FUNCTION__);
return;
}
- addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (addr == NULL) goto Fail;
- callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
- devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
+ devname = sCallbackEnv->NewByteArray(sizeof(bt_bdname_t));
if (devname == NULL) goto Fail;
- callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
+ sCallbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
- callbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, addr, devname, cod,
+ sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, addr, devname, cod,
min_16_digits);
-
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
- callbackEnv->DeleteLocalRef(addr);
- callbackEnv->DeleteLocalRef(devname);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(devname);
return;
Fail:
- if (addr) callbackEnv->DeleteLocalRef(addr);
- if (devname) callbackEnv->DeleteLocalRef(devname);
- ALOGE("Error while allocating in: %s", __FUNCTION__);
+ if (addr) sCallbackEnv->DeleteLocalRef(addr);
+ if (devname) sCallbackEnv->DeleteLocalRef(devname);
+ ALOGE("Error while allocating in: %s", __func__);
}
static void ssp_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod,
bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
jbyteArray addr = NULL;
jbyteArray devname = NULL;
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
if (!bd_addr) {
ALOGE("Address is null in %s", __FUNCTION__);
return;
}
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (addr == NULL) goto Fail;
- callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
- devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
+ devname = sCallbackEnv->NewByteArray(sizeof(bt_bdname_t));
if (devname == NULL) goto Fail;
- callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
+ sCallbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
- callbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, addr, devname, cod,
+ sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, addr, devname, cod,
(jint) pairing_variant, pass_key);
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
- callbackEnv->DeleteLocalRef(addr);
- callbackEnv->DeleteLocalRef(devname);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(devname);
return;
Fail:
- if (addr) callbackEnv->DeleteLocalRef(addr);
- if (devname) callbackEnv->DeleteLocalRef(devname);
+ if (addr) sCallbackEnv->DeleteLocalRef(addr);
+ if (devname) sCallbackEnv->DeleteLocalRef(devname);
ALOGE("Error while allocating in: %s", __FUNCTION__);
}
vm->AttachCurrentThread(&callbackEnv, &args);
ALOGV("Callback thread attached: %p", callbackEnv);
} else if (event == DISASSOCIATE_JVM) {
- if (!checkCallbackThread()) {
+ if (callbackEnv != AndroidRuntime::getJNIEnv()) {
ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
return;
}
}
static void energy_info_recv_callback(bt_activity_energy_info *p_energy_info,
- bt_uid_traffic_t* uid_data)
-{
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- return;
- }
+ bt_uid_traffic_t* uid_data) {
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jsize len = 0;
for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
len++;
}
- jobjectArray array = callbackEnv->NewObjectArray(len, android_bluetooth_UidTraffic.clazz, NULL);
+ jobjectArray array = sCallbackEnv->NewObjectArray(len, android_bluetooth_UidTraffic.clazz, NULL);
jsize i = 0;
for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
- jobject uidObj = callbackEnv->NewObject(android_bluetooth_UidTraffic.clazz,
+ jobject uidObj = sCallbackEnv->NewObject(android_bluetooth_UidTraffic.clazz,
android_bluetooth_UidTraffic.constructor,
(jint) data->app_uid, (jlong) data->rx_bytes,
(jlong) data->tx_bytes);
- callbackEnv->SetObjectArrayElement(array, i++, uidObj);
- callbackEnv->DeleteLocalRef(uidObj);
+ sCallbackEnv->SetObjectArrayElement(array, i++, uidObj);
+ sCallbackEnv->DeleteLocalRef(uidObj);
}
- callbackEnv->CallVoidMethod(sJniAdapterServiceObj, method_energyInfo, p_energy_info->status,
+ sCallbackEnv->CallVoidMethod(sJniAdapterServiceObj, method_energyInfo, p_energy_info->status,
p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time,
p_energy_info->idle_time, p_energy_info->energy_used, array);
- checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
- callbackEnv->DeleteLocalRef(array);
+ sCallbackEnv->DeleteLocalRef(array);
}
static bt_callbacks_t sBluetoothCallbacks = {
#define LOG_NDEBUG 0
-#define CHECK_CALLBACK_ENV \
- if (!checkCallbackThread()) { \
- error("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
- return; \
- }
-
#include "com_android_bluetooth.h"
#include "hardware/bt_gatt.h"
#include "utils/Log.h"
static const btgatt_interface_t *sGattIf = NULL;
static jobject mCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
-
-static bool checkCallbackThread() {
- sCallbackEnv = getCallbackEnv();
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
- return true;
-}
/**
* BTA client callbacks
void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
clientIf, UUID_PARAMS(app_uuid));
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, vector<uint8_t> adv_data)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
jbyteArray jb = sCallbackEnv->NewByteArray(62);
sCallbackEnv->SetByteArrayRegion(jb, 0, 62, (jbyte *) adv_data.data());
sCallbackEnv->DeleteLocalRef(address);
sCallbackEnv->DeleteLocalRef(jb);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected,
clientIf, conn_id, status, address);
sCallbackEnv->DeleteLocalRef(address);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected,
clientIf, conn_id, status, address);
sCallbackEnv->DeleteLocalRef(address);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_search_complete_cb(int conn_id, int status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted,
conn_id, status);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_register_for_notification_cb(int conn_id, int registered, int status, uint16_t handle)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications,
conn_id, status, registered, handle);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, &p_data->bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), &p_data->bda);
jbyteArray jb = sCallbackEnv->NewByteArray(p_data->len);
sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->len, (jbyte *) p_data->value);
sCallbackEnv->DeleteLocalRef(address);
sCallbackEnv->DeleteLocalRef(jb);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jbyteArray jb;
if ( status == 0 ) //successful
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic,
conn_id, status, p_data->handle, jb);
sCallbackEnv->DeleteLocalRef(jb);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_write_characteristic_cb(int conn_id, int status, uint16_t handle)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic
, conn_id, status, handle);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_execute_write_cb(int conn_id, int status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted
, conn_id, status);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jbyteArray jb;
if ( p_data->value.len != 0 )
conn_id, status, p_data->handle, jb);
sCallbackEnv->DeleteLocalRef(jb);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_write_descriptor_cb(int conn_id, int status, uint16_t handle)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor
, conn_id, status, handle);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi,
client_if, address, rssi, status);
sCallbackEnv->DeleteLocalRef(address);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_advertise_cb(int status, int client_if)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAdvertiseCallback, status, client_if);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_configure_mtu_cb(int conn_id, int status, int mtu)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConfigureMTU,
conn_id, status, mtu);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_scan_filter_cfg_cb(int action, int client_if, int status, int filt_type,
int avbl_space)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterConfig,
action, status, client_if, filt_type, avbl_space);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_scan_filter_param_cb(int action, int client_if, int status, int avbl_space)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterParamsConfigured,
action, status, client_if, avbl_space);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_scan_filter_status_cb(int action, int client_if, int status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterEnableDisabled,
action, status, client_if);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_congestion_cb(int conn_id, bool congested)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion, conn_id, congested);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_batchscan_cfg_storage_cb(int client_if, int status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStorageConfigured, status, client_if);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_batchscan_startstop_cb(int startstop_action, int client_if, int status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStartStopped, startstop_action,
status, client_if);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_batchscan_reports_cb(int client_if, int status, int report_format,
int num_records, std::vector<uint8_t> data)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jbyteArray jb = sCallbackEnv->NewByteArray(data.size());
sCallbackEnv->SetByteArrayRegion(jb, 0, data.size(), (jbyte *) data.data());
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanReports, status, client_if,
report_format, num_records, jb);
sCallbackEnv->DeleteLocalRef(jb);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_batchscan_threshold_cb(int client_if)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanThresholdCrossed, client_if);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_track_adv_event_cb(btgatt_track_adv_info_t *p_adv_track_info)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jobject trackadv_obj = NULL;
- jstring address = bdaddr2newjstr(sCallbackEnv, &p_adv_track_info->bd_addr);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), &p_adv_track_info->bd_addr);
jbyteArray jb_adv_pkt = sCallbackEnv->NewByteArray(p_adv_track_info->adv_pkt_len);
jbyteArray jb_scan_rsp = sCallbackEnv->NewByteArray(p_adv_track_info->scan_rsp_len);
sCallbackEnv->DeleteLocalRef(jb_adv_pkt);
sCallbackEnv->DeleteLocalRef(jb_scan_rsp);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgattc_scan_parameter_setup_completed_cb(int client_if, btgattc_error_t status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanParamSetupCompleted, status, client_if);
- checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
}
void fillGattDbElementArray(JNIEnv *env, jobject *array, const btgatt_db_element_t *db, int count) {
void btgattc_get_gatt_db_cb(int conn_id, btgatt_db_element_t *db, int count)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
jobject array = sCallbackEnv->NewObject(arrayListclazz, sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V"));
- fillGattDbElementArray(sCallbackEnv, &array, db, count);
+ fillGattDbElementArray(sCallbackEnv.get(), &array, db, count);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetGattDb, conn_id, array);
sCallbackEnv->DeleteLocalRef(array);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static const btgatt_client_callbacks_t sGattClientCallbacks = {
*/
void ble_advertiser_register_cb(bt_uuid_t uuid, uint8_t advertiser_id, uint8_t status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAdvertiserRegistered,
status, advertiser_id, UUID_PARAMS(&uuid));
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void ble_advertiser_set_params_cb(uint8_t advertiser_id, uint8_t status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvSetParams, status, advertiser_id);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void ble_advertiser_setadv_data_cb(uint8_t advertiser_id, uint8_t status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvSetAdvData, status, advertiser_id);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void ble_advertiser_enable_cb(bool enable, uint8_t advertiser_id, uint8_t status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvEnable, status, advertiser_id, enable);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
/**
void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered
, status, server_if, UUID_PARAMS(uuid));
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected,
address, connected, conn_id, server_if);
sCallbackEnv->DeleteLocalRef(address);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_service_added_cb(int status, int server_if,
vector<btgatt_db_element_t> service)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
jobject array = sCallbackEnv->NewObject(arrayListclazz,
sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V"));
- fillGattDbElementArray(sCallbackEnv, &array, service.data(), service.size());
+ fillGattDbElementArray(sCallbackEnv.get(), &array, service.data(), service.size());
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status,
server_if, array);
sCallbackEnv->DeleteLocalRef(array);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status,
server_if, srvc_handle);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status,
server_if, srvc_handle);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_request_read_characteristic_cb(int conn_id, int trans_id, bt_bdaddr_t *bda,
int attr_handle, int offset, bool is_long)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadCharacteristic,
address, conn_id, trans_id, attr_handle,
offset, is_long);
sCallbackEnv->DeleteLocalRef(address);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_request_read_descriptor_cb(int conn_id, int trans_id, bt_bdaddr_t *bda,
int attr_handle, int offset, bool is_long)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadDescriptor,
address, conn_id, trans_id, attr_handle,
offset, is_long);
sCallbackEnv->DeleteLocalRef(address);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_request_write_characteristic_cb(int conn_id, int trans_id,
int offset, bool need_rsp, bool is_prep,
vector<uint8_t> value)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
jbyteArray val = sCallbackEnv->NewByteArray(value.size());
if (val) sCallbackEnv->SetByteArrayRegion(val, 0, value.size(), (jbyte*)value.data());
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerWriteCharacteristic,
offset, value.size(), need_rsp, is_prep, val);
sCallbackEnv->DeleteLocalRef(address);
sCallbackEnv->DeleteLocalRef(val);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_request_write_descriptor_cb(int conn_id, int trans_id,
int offset, bool need_rsp, bool is_prep,
vector<uint8_t> value)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
jbyteArray val = sCallbackEnv->NewByteArray(value.size());
if (val) sCallbackEnv->SetByteArrayRegion(val, 0, value.size(), (jbyte*)value.data());
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerWriteDescriptor,
offset, value.size(), need_rsp, is_prep, val);
sCallbackEnv->DeleteLocalRef(address);
sCallbackEnv->DeleteLocalRef(val);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_request_exec_write_cb(int conn_id, int trans_id,
bt_bdaddr_t *bda, int exec_write)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
- jstring address = bdaddr2newjstr(sCallbackEnv, bda);
+ jstring address = bdaddr2newjstr(sCallbackEnv.get(), bda);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite,
address, conn_id, trans_id, exec_write);
sCallbackEnv->DeleteLocalRef(address);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_response_confirmation_cb(int status, int handle)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted,
status, handle);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_indication_sent_cb(int conn_id, int status)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent,
conn_id, status);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_congestion_cb(int conn_id, bool congested)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion, conn_id, congested);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
void btgatts_mtu_changed_cb(int conn_id, int mtu)
{
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerMtuChanged, conn_id, mtu);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static const btgatt_server_callbacks_t sGattServerCallbacks = {
#define LOG_NDEBUG 0
-#define CHECK_CALLBACK_ENV \
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
- return; \
- }
-
#include "com_android_bluetooth.h"
#include "hardware/bt_hl.h"
#include "utils/Log.h"
static const bthl_interface_t *sBluetoothHdpInterface = NULL;
static jobject mCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
-
-static bool checkCallbackThread() {
- sCallbackEnv = getCallbackEnv();
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) {
- ALOGE("Callback env check fail: env: %p, callback: %p", env, sCallbackEnv);
- return false;
- }
- return true;
-}
// Define callback functions
static void app_registration_state_callback(int app_id, bthl_app_reg_state_t state) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAppRegistrationState, app_id,
(jint) state);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void channel_state_callback(int app_id, bt_bdaddr_t *bd_addr, int mdep_cfg_index,
jbyteArray addr;
jobject fileDescriptor = NULL;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for channel state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
// TODO(BT) check if fd is only valid for BTHH_CONN_STATE_CONNECTED state
if (state == BTHL_CONN_STATE_CONNECTED) {
- fileDescriptor = jniCreateFileDescriptor(sCallbackEnv, fd);
+ fileDescriptor = jniCreateFileDescriptor(sCallbackEnv.get(), fd);
if (!fileDescriptor) {
ALOGE("Failed to convert file descriptor, fd: %d", fd);
sCallbackEnv->DeleteLocalRef(addr);
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onChannelStateChanged, app_id, addr,
mdep_cfg_index, channel_id, (jint) state, fileDescriptor);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
#define LOG_NDEBUG 0
-#define CHECK_CALLBACK_ENV \
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
- return; \
- }
-
#include "com_android_bluetooth.h"
#include "hardware/bt_hf.h"
#include "utils/Log.h"
static const bthf_interface_t *sBluetoothHfpInterface = NULL;
static jobject mCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
-
-static bool checkCallbackThread() {
- // Always fetch the latest callbackEnv from AdapterService.
- // Caching this could cause this sCallbackEnv to go out-of-sync
- // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
- // is received
- //if (sCallbackEnv == NULL) {
- sCallbackEnv = getCallbackEnv();
- //}
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
- return true;
-}
static jbyteArray marshall_bda(bt_bdaddr_t* bd_addr)
{
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return NULL;
+
jbyteArray addr;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return NULL;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
ALOGI("%s", __FUNCTION__);
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged,
(jint) state, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void audio_state_callback(bthf_audio_state_t state, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, (jint) state, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void voice_recognition_callback(bthf_vr_state_t state, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint) state, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void answer_call_callback(bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void hangup_call_callback(bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHangupCall, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void volume_control_callback(bthf_volume_type_t type, int volume, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChanged, (jint) type,
(jint) volume, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void dial_call_callback(char *number, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
jstring js_number = sCallbackEnv->NewStringUTF(number);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDialCall,
js_number, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(js_number);
sCallbackEnv->DeleteLocalRef(addr);
}
static void dtmf_cmd_callback(char dtmf, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
// TBD dtmf has changed from int to char
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void noice_reduction_callback(bthf_nrec_t nrec, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiceReductionEnable,
nrec == BTHF_NREC_START, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void wbs_callback(bthf_wbs_config_t wbs_config, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
if ((addr = marshall_bda(bd_addr)) == NULL)
return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWBS, wbs_config, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void at_chld_callback(bthf_chld_type_t chld, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void at_cnum_callback(bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void at_cind_callback(bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void at_cops_callback(bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void at_clcc_callback(bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void unknown_at_callback(char *at_string, bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
jstring js_at_string = sCallbackEnv->NewStringUTF(at_string);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownAt,
js_at_string, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(js_at_string);
sCallbackEnv->DeleteLocalRef(addr);
}
static void key_pressed_callback(bt_bdaddr_t* bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void at_bind_callback(char *at_string, bt_bdaddr_t *bd_addr) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jbyteArray addr = marshall_bda(bd_addr);
if (addr == NULL)
jstring js_at_string = sCallbackEnv->NewStringUTF(at_string);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBind, js_at_string, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(js_at_string);
sCallbackEnv->DeleteLocalRef(addr);
}
static void at_biev_callback(bthf_hf_ind_type_t ind_id, int ind_value, bt_bdaddr_t *bd_addr) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jbyteArray addr = marshall_bda(bd_addr);
if (addr == NULL)
return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBiev, ind_id, (jint)ind_value, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
#include "utils/Log.h"
#include "android_runtime/AndroidRuntime.h"
-#define CHECK_CALLBACK_ENV \
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
- return; \
- }
-
namespace android {
static bthf_client_interface_t *sBluetoothHfpClientInterface = NULL;
static jobject mCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
static jmethodID method_onConnectionStateChanged;
static jmethodID method_onAudioStateChanged;
static jmethodID method_onLastVoiceTagNumber;
static jmethodID method_onRingIndication;
-static bool checkCallbackThread() {
- // Always fetch the latest callbackEnv from AdapterService.
- // Caching this could cause this sCallbackEnv to go out-of-sync
- // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
- // is received
- sCallbackEnv = getCallbackEnv();
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
- return true;
-}
-
static void connection_state_cb(bthf_client_connection_state_t state, unsigned int peer_feat, unsigned int chld_feat, bt_bdaddr_t *bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, (jint) state, (jint) peer_feat, (jint) chld_feat, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void audio_state_cb(bthf_client_audio_state_t state, bt_bdaddr_t *bd_addr) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, (jint) state, addr);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void vr_cmd_cb(bthf_client_vr_state_t state) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint) state);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void network_state_cb (bthf_client_network_state_t state) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNetworkState, (jint) state);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void network_roaming_cb (bthf_client_service_type_t type) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNetworkRoaming, (jint) type);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void network_signal_cb (int signal) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNetworkSignal, (jint) signal);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void battery_level_cb (int level) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatteryLevel, (jint) level);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void current_operator_cb (const char *name) {
jstring js_name;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
js_name = sCallbackEnv->NewStringUTF(name);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCurrentOperator, js_name);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(js_name);
}
static void call_cb (bthf_client_call_t call) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCall, (jint) call);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void callsetup_cb (bthf_client_callsetup_t callsetup) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallSetup, (jint) callsetup);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void callheld_cb (bthf_client_callheld_t callheld) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallHeld, (jint) callheld);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void resp_and_hold_cb (bthf_client_resp_and_hold_t resp_and_hold) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRespAndHold, (jint) resp_and_hold);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void clip_cb (const char *number) {
jstring js_number;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
js_number = sCallbackEnv->NewStringUTF(number);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClip, js_number);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(js_number);
}
static void call_waiting_cb (const char *number) {
jstring js_number;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
js_number = sCallbackEnv->NewStringUTF(number);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallWaiting, js_number);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(js_number);
}
const char *number) {
jstring js_number;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
js_number = sCallbackEnv->NewStringUTF(number);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCurrentCalls, index, dir, state, mpty, js_number);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(js_number);
}
static void volume_change_cb (bthf_client_volume_type_t type, int volume) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChange, (jint) type, (jint) volume);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void cmd_complete_cb (bthf_client_cmd_complete_t type, int cme) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCmdResult, (jint) type, (jint) cme);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void subscriber_info_cb (const char *name, bthf_client_subscriber_service_type_t type) {
jstring js_name;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
js_name = sCallbackEnv->NewStringUTF(name);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSubscriberInfo, js_name, (jint) type);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(js_name);
}
static void in_band_ring_cb (bthf_client_in_band_ring_state_t in_band) {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onInBandRing, (jint) in_band);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static void last_voice_tag_number_cb (const char *number) {
jstring js_number;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
js_number = sCallbackEnv->NewStringUTF(number);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onLastVoiceTagNumber, js_number);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(js_number);
}
static void ring_indication_cb () {
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRingIndication);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static bthf_client_callbacks_t sBluetoothHfpClientCallbacks = {
#define LOG_NDEBUG 1
-#define CHECK_CALLBACK_ENV \
- if (!checkCallbackThread()) { \
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
- return; \
- }
-
#include "com_android_bluetooth.h"
#include "hardware/bt_hh.h"
#include "utils/Log.h"
static const bthh_interface_t *sBluetoothHidInterface = NULL;
static jobject mCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
-
-static bool checkCallbackThread() {
-
- // Always fetch the latest callbackEnv from AdapterService.
- // Caching this could cause this sCallbackEnv to go out-of-sync
- // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
- // is received
-
- sCallbackEnv = getCallbackEnv();
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
- return true;
-}
static void connection_state_callback(bt_bdaddr_t *bd_addr, bthh_connection_state_t state) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for HID channel state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectStateChanged, addr, (jint) state);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
static void get_protocol_mode_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,bthh_protocol_mode_t mode) {
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
if (hh_status != BTHH_OK) {
ALOGE("BTHH Status is not OK!");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for get protocal mode callback");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetProtocolMode, addr, (jint) mode);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
jbyteArray addr;
jbyteArray data;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
if (hh_status != BTHH_OK) {
ALOGE("BTHH Status is not OK!");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for get report callback");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
data = sCallbackEnv->NewByteArray(rpt_size);
if (!data) {
ALOGE("Fail to new jbyteArray data for get report callback");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
return;
}
sCallbackEnv->SetByteArrayRegion(data, 0, rpt_size, (jbyte *) rpt_data);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetReport, addr, data, (jint) rpt_size);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
sCallbackEnv->DeleteLocalRef(data);
}
ALOGV("call to virtual_unplug_callback");
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for HID channel state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVirtualUnplug, addr, (jint) hh_status);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
/*jbyteArray addr;
jint status = hh_status;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for HID report");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVirtualUnplug, addr, status);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);*/
}
{
jbyteArray addr;
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr for handshake callback");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHandshake, addr, (jint) hh_status);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
#define LOG_NDEBUG 0
-#define CHECK_CALLBACK_ENV \
- if (!checkCallbackThread()) { \
- error("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
- return; \
- }
-
#include "com_android_bluetooth.h"
#include "hardware/bt_pan.h"
#include "utils/Log.h"
static const btpan_interface_t *sPanIf = NULL;
static jobject mCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
-
-static bool checkCallbackThread() {
- sCallbackEnv = getCallbackEnv();
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
- return true;
-}
static void control_state_callback(btpan_control_state_t state, int local_role, bt_status_t error,
const char* ifname) {
error("Callbacks Obj is NULL: '%s", __FUNCTION__);
return;
}
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
jstring js_ifname = sCallbackEnv->NewStringUTF(ifname);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onControlStateChanged, (jint)local_role, (jint)state,
(jint)error, js_ifname);
error("Callbacks Obj is NULL: '%s", __FUNCTION__);
return;
}
- CHECK_CALLBACK_ENV
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (!addr) {
error("Fail to new jbyteArray bd addr for PAN channel state");
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
return;
}
sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectStateChanged, addr, (jint) state,
(jint)error, (jint)local_role, (jint)remote_role);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
sCallbackEnv->DeleteLocalRef(addr);
}
#define UUID_MAX_LENGTH 16
#define IS_UUID(u1,u2) !memcmp(u1,u2,UUID_MAX_LENGTH)
-
namespace android {
static jmethodID method_sdpRecordFoundCallback;
static jmethodID method_sdpMasRecordFoundCallback;
};
static jobject sCallbacksObj = NULL;
-static JNIEnv *sCallbackEnv = NULL;
-
-static bool checkCallbackThread() {
- sCallbackEnv = getCallbackEnv();
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (sCallbackEnv != env || sCallbackEnv == NULL) {
- ALOGE("Callback env check fail: env: %p, callback: %p", env, sCallbackEnv);
- return false;
- }
- return true;
-}
static void initializeNative(JNIEnv *env, jobject object) {
const bt_interface_t* btInf;
int i = 0;
bluetooth_sdp_record* record;
- if (!checkCallbackThread()) {
- ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
- goto clean;
- }
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
if (addr == NULL) goto clean;
sCallbackEnv->DeleteLocalRef(service_name);
if (addr != NULL) sCallbackEnv->DeleteLocalRef(addr);
if (uuid != NULL) sCallbackEnv->DeleteLocalRef(uuid);
- checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
static jint sdpCreateMapMasRecordNative(JNIEnv *env, jobject obj, jstring name_str, jint mas_id,