AVRCP: Add lock in JNI to fix race conditions
Add lock for callback methods to avoid the null
errors in JNI due to cleanup and Native calls
race condition.
CRs-Fixed: 2437481
Change-Id: I0dfea44aff4cbc1ebc6235c80463101fc700322a
diff --git a/packages_apps_bluetooth_ext/jni/com_android_bluetooth_avrcp_ext.cpp b/packages_apps_bluetooth_ext/jni/com_android_bluetooth_avrcp_ext.cpp
index 9774d2a..cf4e968 100644
--- a/packages_apps_bluetooth_ext/jni/com_android_bluetooth_avrcp_ext.cpp
+++ b/packages_apps_bluetooth_ext/jni/com_android_bluetooth_avrcp_ext.cpp
@@ -59,6 +59,7 @@
static const btrc_interface_t *sBluetoothAvrcpInterface = NULL;
static jobject mCallbacksObj = NULL;
static std::shared_timed_mutex callbacks_mutex;
+static std::shared_timed_mutex interface_mutex;
/* Function declarations */
static bool copy_item_attributes(JNIEnv* env, jobject object,
@@ -122,6 +123,7 @@
RawAddress* bd_addr) {
ALOGI("%s", __FUNCTION__);
CallbackEnv sCallbackEnv(__func__);
+ std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -145,6 +147,7 @@
static void btavrcp_get_player_attribute_id_callback(RawAddress* bd_addr) {
ALOGI("%s", __FUNCTION__);
CallbackEnv sCallbackEnv(__func__);
+ std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -169,6 +172,7 @@
RawAddress* bd_addr) {
ALOGI("%s", __FUNCTION__);
CallbackEnv sCallbackEnv(__func__);
+ std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -202,6 +206,7 @@
{
ALOGI("%s", __FUNCTION__);
CallbackEnv sCallbackEnv(__func__);
+ std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -242,6 +247,7 @@
{
ALOGI("%s", __FUNCTION__);
CallbackEnv sCallbackEnv(__func__);
+ std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -274,6 +280,7 @@
{
ALOGI("%s", __FUNCTION__);
CallbackEnv sCallbackEnv(__func__);
+ std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -822,6 +829,7 @@
static void initNative(JNIEnv* env, jobject object,
jint maxAvrcpConnections) {
std::unique_lock<std::shared_timed_mutex> lock(callbacks_mutex);
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
const bt_interface_t* btInf = getBluetoothInterface();
if (btInf == NULL) {
ALOGE("Bluetooth module is not loaded");
@@ -861,6 +869,7 @@
static void cleanupNative(JNIEnv* env, jobject object) {
std::unique_lock<std::shared_timed_mutex> lock(callbacks_mutex);
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
const bt_interface_t* btInf = getBluetoothInterface();
if (btInf == NULL) {
ALOGE("Bluetooth module is not loaded");
@@ -881,6 +890,7 @@
static jboolean getPlayStatusRspNative(JNIEnv* env, jobject object,
jbyteArray address, jint playStatus,
jint songLen, jint songPos) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -907,6 +917,7 @@
}
static jboolean updatePlayStatusToStack(JNIEnv *env ,jobject object, jint playStatus) {
ALOGE("%s",__func__);
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null ", __func__);
return JNI_FALSE;
@@ -926,6 +937,7 @@
int i;
jbyte *attr;
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) return JNI_FALSE;
if (!address) {
@@ -983,6 +995,7 @@
int i;
jbyte *attr;
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) return JNI_FALSE;
if (!address) {
@@ -1041,6 +1054,7 @@
int i;
jbyte *attr;
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) return JNI_FALSE;
if (!address) {
@@ -1092,6 +1106,7 @@
jbyte *addr;
btrc_status_t player_rsp = (btrc_status_t) attr_status;
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) return JNI_FALSE;
if (!address) {
@@ -1124,6 +1139,7 @@
const char* textStr;
jbyte *arr ;
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) return JNI_FALSE;
if (!address) {
@@ -1191,7 +1207,8 @@
const char* textStr;
jbyte *arr ;
- //ALOGE("sendValueTextRspNative");
+ ALOGE("sendValueTextRspNative");
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) return JNI_FALSE;
if (!address) {
@@ -1250,6 +1267,7 @@
jbyteArray address, jbyte numAttr,
jintArray attrIds,
jobjectArray textArray) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1322,6 +1340,7 @@
jbyteArray address, jint rspStatus,
jbyte numAttr, jintArray attrIds,
jobjectArray textArray) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1395,6 +1414,7 @@
jbyte *attr;
btrc_register_notification_t *param= NULL;
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) return JNI_FALSE;
if (!address) {
@@ -1448,6 +1468,7 @@
jint type,
jint playStatus,
jbyteArray address) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1483,6 +1504,7 @@
jint type,
jbyteArray track,
jbyteArray address) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1531,6 +1553,7 @@
jobject object, jint type,
jint playPos,
jbyteArray address) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1565,6 +1588,7 @@
jobject object,
jint type,
jbyteArray address) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1598,6 +1622,7 @@
jint type,
jint uidCounter,
jbyteArray address) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1631,6 +1656,7 @@
static jboolean registerNotificationRspAddrPlayerChangedNative(
JNIEnv* env, jobject object, jint type, jint playerId, jint uidCounter,
jbyteArray address) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1667,6 +1693,7 @@
jobject object,
jint type,
jbyteArray address) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1699,6 +1726,7 @@
}
static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume, jbyteArray address) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1733,6 +1761,7 @@
jbyteArray playerTypes, jintArray playerSubtypes,
jbyteArray playStatusValues, jshortArray featureBitmask,
jobjectArray textArray) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1841,6 +1870,7 @@
jbyteArray playable, jbyteArray itemType, jbyteArray itemUidArray,
jobjectArray displayNameArray, jintArray numAttrs, jintArray attributesIds,
jobjectArray attributesArray) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -1980,6 +2010,7 @@
static jboolean setAddressedPlayerRspNative(JNIEnv* env, jobject object,
jbyteArray address,
jint rspStatus) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -2011,6 +2042,7 @@
jbyteArray address, jint rspStatus,
jbyte depth, jint numItems,
jobjectArray textArray) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -2080,6 +2112,7 @@
static jboolean changePathRspNative(JNIEnv* env, jobject object,
jbyteArray address, jint rspStatus,
jint numItems) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -2111,6 +2144,7 @@
static jboolean searchRspNative(JNIEnv* env, jobject object, jbyteArray address,
jint rspStatus, jint uidCounter,
jint numItems) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -2142,6 +2176,7 @@
static jboolean playItemRspNative(JNIEnv* env, jobject object,
jbyteArray address, jint rspStatus) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -2172,6 +2207,7 @@
static jboolean getTotalNumOfItemsRspNative(JNIEnv* env, jobject object,
jbyteArray address, jint rspStatus,
jint uidCounter, jint numItems) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -2202,6 +2238,7 @@
static jboolean addToNowPlayingRspNative(JNIEnv* env, jobject object,
jbyteArray address, jint rspStatus) {
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) {
ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
return JNI_FALSE;
@@ -2235,6 +2272,7 @@
bt_status_t status = BT_STATUS_SUCCESS;
jbyte *addr;
+ std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
if (!sBluetoothAvrcpInterface) return JNI_FALSE;
if (!address) {