summaryrefslogtreecommitdiffstats
path: root/jni/com_android_bluetooth_avrcp_controller.cpp
diff options
context:
space:
mode:
authorAnubhavGupta <anubhavg@codeaurora.org>2015-02-27 19:08:36 +0530
committerLinux Build Service Account <lnxbuild@localhost>2015-10-06 03:25:43 -0600
commit442962cde4c933ba91eeeb422e48d063fa5fa0fb (patch)
treed8d1d124172a0675397899fc42f0daf211f13d0a /jni/com_android_bluetooth_avrcp_controller.cpp
parentdb525f6a5d47ea8934dd58cffff452da89489f30 (diff)
downloadandroid_packages_apps_Bluetooth-442962cde4c933ba91eeeb422e48d063fa5fa0fb.tar.gz
android_packages_apps_Bluetooth-442962cde4c933ba91eeeb422e48d063fa5fa0fb.tar.bz2
android_packages_apps_Bluetooth-442962cde4c933ba91eeeb422e48d063fa5fa0fb.zip
Bluetooth : Support for AVRCP 1.3 Controller
- Content Provider Implementation for AVRCP MetaData - Handling of AVRCP Commands and Events - Interface for AudioManger to support AbsVol Change-Id: I5e1f768ddfa6c089667874c5151a412ae79052bd Bluetooth: Avrcp Controller 1.3 Support - send GetPlayStatus on state transition from paused/stopped to playing. - indentation correction Change-Id: Ifa259038383e0652ff7dcb345367d8f67c3c80be Bluetooth: AVRCP Controller fixes - Reset metadata if remote does not support a particular Element Attribute - Fetch playerapplicationattributes on track change - Proper update of negative values from remote Usecase: Switch player on TG and check metadata, playerappsetting Failure: Remote device does not call Event_APP_SETTING_CHANGED when we switch between player. If new player does not update metadata, we were showing stale data Solution: Reset metadata if not supported by remote send getplayerapplicatoin on track change Change-Id: Ia7859261336ccdb447d330626b434fefd4abee6f
Diffstat (limited to 'jni/com_android_bluetooth_avrcp_controller.cpp')
-rw-r--r--jni/com_android_bluetooth_avrcp_controller.cpp558
1 files changed, 555 insertions, 3 deletions
diff --git a/jni/com_android_bluetooth_avrcp_controller.cpp b/jni/com_android_bluetooth_avrcp_controller.cpp
index 9e32721e9..1fa588911 100644
--- a/jni/com_android_bluetooth_avrcp_controller.cpp
+++ b/jni/com_android_bluetooth_avrcp_controller.cpp
@@ -1,4 +1,6 @@
/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Not a Contribution
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,6 +30,18 @@
namespace android {
static jmethodID method_handlePassthroughRsp;
static jmethodID method_onConnectionStateChanged;
+static jmethodID method_getRcFeatures;
+static jmethodID method_handleGetCapabilitiesResponse;
+static jmethodID method_handleListPlayerApplicationSettingsAttrib;
+static jmethodID method_handleListPlayerApplicationSettingValue;
+static jmethodID method_handleCurrentPlayerApplicationSettingsResponse;
+static jmethodID method_handleNotificationRsp;
+static jmethodID method_handleGetElementAttributes;
+static jmethodID method_handleGetPlayStatus;
+static jmethodID method_handleSetAbsVolume;
+static jmethodID method_handleRegisterNotificationAbsVol;
+static jmethodID method_handleSetPlayerApplicationResponse;
+
static const btrc_ctrl_interface_t *sBluetoothAvrcpInterface = NULL;
static jobject mCallbacksObj = NULL;
@@ -84,11 +98,323 @@ static void btavrcp_connection_state_callback(bool state, bt_bdaddr_t* bd_addr)
sCallbackEnv->DeleteLocalRef(addr);
}
+static void btavrcp_get_rcfeatures_callback(bt_bdaddr_t *bd_addr, int features) {
+ jbyteArray addr;
+
+ ALOGI("%s", __FUNCTION__);
+
+ 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 ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getRcFeatures, addr, (jint)features);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+}
+
+static void btavrcp_getcap_rsp_callback(bt_bdaddr_t *bd_addr, int cap_id,
+ uint32_t* supported_values, int num_supported, uint8_t rsp_type) {
+ jbyteArray addr;
+ jintArray supported_val = NULL;
+
+ ALOGI("%s", __FUNCTION__);
+
+ if (!checkCallbackThread()) { \
+ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
+ return; \
+ }
+
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ supported_val = sCallbackEnv->NewIntArray(num_supported);
+ if ((!addr)||(!supported_val)) {
+ ALOGE("Fail to get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+ sCallbackEnv->SetIntArrayRegion(supported_val, 0, (num_supported), (jint*)(supported_values));
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleGetCapabilitiesResponse, addr,
+ (jint)cap_id,supported_val, (jint)num_supported, (jbyte)rsp_type);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(supported_val);
+}
+
+static void btavrcp_list_player_app_setting_attrib_rsp_callback(bt_bdaddr_t *bd_addr,
+ uint8_t* supported_attribs, int num_attrib, uint8_t rsp_type) {
+ jbyteArray addr;
+ jbyteArray supported_val;
+
+ ALOGI("%s", __FUNCTION__);
+
+ if (!checkCallbackThread()) { \
+ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
+ return; \
+ }
+
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ supported_val = sCallbackEnv->NewByteArray(num_attrib);
+ if ((!addr)||(!supported_val)) {
+ ALOGE("Fail to get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+ sCallbackEnv->SetByteArrayRegion(supported_val, 0, (num_attrib), (jbyte*)(supported_attribs));
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleListPlayerApplicationSettingsAttrib,
+ addr, supported_val,(jint)num_attrib, (jbyte)rsp_type);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(supported_val);
+}
+
+static void btavrcp_list_player_app_setting_value_rsp_callback(bt_bdaddr_t *bd_addr,
+ uint8_t* supported_values, uint8_t num_supported, uint8_t rsp_type) {
+ jbyteArray addr;
+ jbyteArray supported_val;
+
+ ALOGI("%s", __FUNCTION__);
+
+ if (!checkCallbackThread()) { \
+ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
+ return; \
+ }
+
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ supported_val = sCallbackEnv->NewByteArray(num_supported);
+ if ((!addr)||(!supported_val)) {
+ ALOGE("Fail to get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+ sCallbackEnv->SetByteArrayRegion(supported_val, 0,(num_supported), (jbyte*)(supported_values));
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleListPlayerApplicationSettingValue,
+ addr, supported_val,(jbyte)num_supported, (jbyte)rsp_type);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(supported_val);
+}
+
+static void btavrcp_current_player_app_setting_rsp_callback(bt_bdaddr_t *bd_addr,
+ uint8_t* supported_ids,uint8_t* supported_values, uint8_t num_attrib, uint8_t rsp_type) {
+ jbyteArray addr;
+ jbyteArray supported_attrib_ids;
+ jbyteArray supported_val;
+
+ ALOGI("%s", __FUNCTION__);
+
+ if (!checkCallbackThread()) { \
+ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
+ return; \
+ }
+
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ supported_val = sCallbackEnv->NewByteArray(num_attrib);
+ supported_attrib_ids = sCallbackEnv->NewByteArray(num_attrib);
+ if ((!addr)||(!supported_val)) {
+ ALOGE("Fail to get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+ sCallbackEnv->SetByteArrayRegion(supported_val, 0, (num_attrib), (jbyte*)(supported_values));
+ sCallbackEnv->SetByteArrayRegion(supported_attrib_ids, 0, (num_attrib),
+ (jbyte*)(supported_ids));
+ sCallbackEnv->CallVoidMethod(mCallbacksObj,
+ method_handleCurrentPlayerApplicationSettingsResponse,addr,supported_attrib_ids,
+ supported_val, (jbyte)num_attrib, (jbyte)rsp_type);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(supported_val);
+ sCallbackEnv->DeleteLocalRef(supported_attrib_ids);
+}
+
+static void btavrcp_set_player_app_setting_rsp_callback(bt_bdaddr_t *bd_addr,uint8_t rsp_type) {
+ jbyteArray addr;
+
+ ALOGI("%s", __FUNCTION__);
+
+ 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 get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleSetPlayerApplicationResponse,
+ addr,(jbyte)rsp_type);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+}
+
+static void btavrcp_notification_rsp_callback(bt_bdaddr_t *bd_addr, uint8_t rsp_type,
+ int rsp_len, uint8_t* notification_rsp) {
+ jbyteArray addr;
+ jbyteArray supported_val;
+
+ ALOGI("%s", __FUNCTION__);
+
+ if (!checkCallbackThread()) { \
+ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
+ return; \
+ }
+
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ supported_val = sCallbackEnv->NewByteArray(rsp_len);
+ if ((!addr)||(!supported_val)) {
+ ALOGE("Fail to get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+ sCallbackEnv->SetByteArrayRegion(supported_val, 0, (rsp_len), (jbyte*)(notification_rsp));
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleNotificationRsp,
+ addr, (jbyte)rsp_type, (jint)rsp_len, supported_val);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(supported_val);
+}
+
+static void btavrcp_get_element_attrib_rsp_callback(bt_bdaddr_t *bd_addr, uint8_t num_attributes,
+ int rsp_len, uint8_t* attrib_rsp,uint8_t rsp_type) {
+ jbyteArray addr;
+ jbyteArray supported_val;
+
+ ALOGI("%s", __FUNCTION__);
+
+ if (!checkCallbackThread()) { \
+ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
+ return; \
+ }
+
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ supported_val = sCallbackEnv->NewByteArray(rsp_len);
+ if ((!addr)||(!supported_val)) {
+ ALOGE("Fail to get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+ sCallbackEnv->SetByteArrayRegion(supported_val, 0, (rsp_len), (jbyte*)(attrib_rsp));
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleGetElementAttributes,
+ addr, (jbyte)num_attributes, (jint)rsp_len,supported_val, (jbyte)rsp_type);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(supported_val);
+}
+
+static void btavrcp_get_playstatus_rsp_callback(bt_bdaddr_t *bd_addr, int param_len,
+ uint8_t* play_status_rsp,uint8_t rsp_type) {
+ jbyteArray addr;
+ jbyteArray supported_val;
+
+ ALOGI("%s", __FUNCTION__);
+
+ if (!checkCallbackThread()) { \
+ ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
+ return; \
+ }
+
+ addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ supported_val = sCallbackEnv->NewByteArray(param_len);
+ if ((!addr)||(!supported_val)) {
+ ALOGE("Fail to get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+ sCallbackEnv->SetByteArrayRegion(supported_val, 0, (param_len), (jbyte*)(play_status_rsp));
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleGetPlayStatus,
+ addr, (jint)param_len, supported_val, (jbyte)rsp_type);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+ sCallbackEnv->DeleteLocalRef(supported_val);
+}
+
+static void btavrcp_set_abs_vol_cmd_callback(bt_bdaddr_t *bd_addr, uint8_t abs_vol) {
+ jbyteArray addr;
+
+ ALOGI("%s", __FUNCTION__);
+
+ 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 get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleSetAbsVolume, addr, (jbyte)abs_vol);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+}
+
+static void btavrcp_register_notification_absvol_callback(bt_bdaddr_t *bd_addr) {
+ jbyteArray addr;
+
+ ALOGI("%s", __FUNCTION__);
+
+ 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 get new array ");
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ return;
+ }
+
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleRegisterNotificationAbsVol, addr);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+}
static btrc_ctrl_callbacks_t sBluetoothAvrcpCallbacks = {
sizeof(sBluetoothAvrcpCallbacks),
btavrcp_passthrough_response_callback,
- btavrcp_connection_state_callback
+ btavrcp_connection_state_callback,
+ btavrcp_get_rcfeatures_callback,
+ btavrcp_getcap_rsp_callback,
+ btavrcp_list_player_app_setting_attrib_rsp_callback,
+ btavrcp_list_player_app_setting_value_rsp_callback,
+ btavrcp_current_player_app_setting_rsp_callback,
+ btavrcp_set_player_app_setting_rsp_callback,
+ btavrcp_notification_rsp_callback,
+ btavrcp_get_element_attrib_rsp_callback,
+ btavrcp_get_playstatus_rsp_callback,
+ btavrcp_set_abs_vol_cmd_callback,
+ btavrcp_register_notification_absvol_callback
};
static void classInitNative(JNIEnv* env, jclass clazz) {
@@ -98,6 +424,39 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
method_onConnectionStateChanged =
env->GetMethodID(clazz, "onConnectionStateChanged", "(Z[B)V");
+ method_getRcFeatures =
+ env->GetMethodID(clazz, "getRcFeatures", "([BI)V");
+
+ method_handleGetCapabilitiesResponse =
+ env->GetMethodID(clazz, "handleGetCapabilitiesResponse", "([BI[IIB)V");
+
+ method_handleListPlayerApplicationSettingsAttrib =
+ env->GetMethodID(clazz, "handleListPlayerApplicationSettingsAttrib", "([B[BIB)V");
+
+ method_handleListPlayerApplicationSettingValue =
+ env->GetMethodID(clazz, "handleListPlayerApplicationSettingValue", "([B[BBB)V");
+
+ method_handleCurrentPlayerApplicationSettingsResponse =
+ env->GetMethodID(clazz, "handleCurrentPlayerApplicationSettingsResponse", "([B[B[BBB)V");
+
+ method_handleNotificationRsp =
+ env->GetMethodID(clazz, "handleNotificationRsp", "([BBI[B)V");
+
+ method_handleGetElementAttributes =
+ env->GetMethodID(clazz, "handleGetElementAttributes", "([BBI[BB)V");
+
+ method_handleGetPlayStatus =
+ env->GetMethodID(clazz, "handleGetPlayStatus", "([BI[BB)V");
+
+ method_handleSetAbsVolume =
+ env->GetMethodID(clazz, "handleSetAbsVolume", "([BB)V");
+
+ method_handleRegisterNotificationAbsVol =
+ env->GetMethodID(clazz, "handleRegisterNotificationAbsVol", "([B)V");
+
+ method_handleSetPlayerApplicationResponse =
+ env->GetMethodID(clazz, "handleSetPlayerApplicationResponse", "([BB)V");
+
ALOGI("%s: succeeds", __FUNCTION__);
}
@@ -183,12 +542,205 @@ static jboolean sendPassThroughCommandNative(JNIEnv *env, jobject object, jbyteA
return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
+static void getCapabilitiesNative(JNIEnv *env, jobject object,jint capability_id) {
+ bt_status_t status;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->getcapabilities_cmd((uint8_t)capability_id))
+ != BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending getCapabilitiesNative command, status: %d", status);
+ }
+}
+
+static void listPlayerApplicationSettingAttributeNative(JNIEnv *env, jobject object) {
+ bt_status_t status;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->list_player_app_setting_attrib_cmd())
+ != BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending listPlAppSettAttribNative command,status: %d", status);
+ }
+}
+
+static void listPlayerApplicationSettingValueNative(JNIEnv *env, jobject object, jbyte attrib_id) {
+ bt_status_t status;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->list_player_app_setting_value_cmd((uint8_t)attrib_id))
+ != BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending listPlAppSettValNative command, status: %d", status);
+ }
+}
+
+static void getPlayerApplicationSettingValuesNative(JNIEnv *env, jobject object, jbyte num_attrib, jbyteArray attrib_ids) {
+ bt_status_t status;
+ uint8_t *pAttrs = NULL;
+ int i;
+ jbyte *attr;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ pAttrs = new uint8_t[num_attrib];
+ if (!pAttrs) {
+ ALOGE("getPlayerApplicationSettingValuesNative: not have enough memeory");
+ return;
+ }
+ attr = env->GetByteArrayElements(attrib_ids, NULL);
+ if (!attr) {
+ delete[] pAttrs;
+ jniThrowIOException(env, EINVAL);
+ return;
+ }
+ for (i = 0; i < num_attrib; ++i) {
+ pAttrs[i] = (uint8_t)attr[i];
+ }
+ if (i < num_attrib) {
+ delete[] pAttrs;
+ env->ReleaseByteArrayElements(attrib_ids, attr, 0);
+ return;
+ }
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->get_player_app_setting_cmd((uint8_t)num_attrib, pAttrs))
+ != BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending getPlAppSettValNative command, status: %d", status);
+ }
+ delete[] pAttrs;
+ env->ReleaseByteArrayElements(attrib_ids, attr, 0);
+}
+
+static void setPlayerApplicationSettingValuesNative(JNIEnv *env, jobject object, jbyte num_attrib, jbyteArray attrib_ids,
+ jbyteArray attrib_val) {
+ bt_status_t status;
+ uint8_t *pAttrs = NULL;
+ uint8_t *pAttrsVal = NULL;
+ int i;
+ jbyte *attr;
+ jbyte *attr_val;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ pAttrs = new uint8_t[num_attrib];
+ pAttrsVal = new uint8_t[num_attrib];
+ if ((!pAttrs) ||(!pAttrsVal)) {
+ ALOGE("setPlayerApplicationSettingValuesNative: not have enough memeory");
+ return;
+ }
+ attr = env->GetByteArrayElements(attrib_ids, NULL);
+ attr_val = env->GetByteArrayElements(attrib_val, NULL);
+ if ((!attr)||(!attr_val)) {
+ delete[] pAttrs;
+ delete[] pAttrsVal;
+ jniThrowIOException(env, EINVAL);
+ return;
+ }
+ for (i = 0; i < num_attrib; ++i) {
+ pAttrs[i] = (uint8_t)attr[i];
+ pAttrsVal[i] = (uint8_t)attr_val[i];
+ }
+ if (i < num_attrib) {
+ delete[] pAttrs;
+ delete[] pAttrsVal;
+ env->ReleaseByteArrayElements(attrib_ids, attr, 0);
+ env->ReleaseByteArrayElements(attrib_val, attr_val, 0);
+ return;
+ }
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->set_player_app_setting_cmd((uint8_t)num_attrib, pAttrs, pAttrsVal))
+ != BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending setPlAppSettValNative command, status: %d", status);
+ }
+ delete[] pAttrs;
+ delete[] pAttrsVal;
+ env->ReleaseByteArrayElements(attrib_ids, attr, 0);
+ env->ReleaseByteArrayElements(attrib_val, attr_val, 0);
+}
+
+static void registerNotificationNative(JNIEnv *env, jobject object, jbyte event_id, jint value ) {
+ bt_status_t status;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->register_notification_cmd((uint8_t)event_id,(uint32_t)value))
+ != BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending registerNotificationNative command, status: %d", status);
+ }
+}
+
+static void getElementAttributeNative(JNIEnv *env, jobject object, jbyte num_attrib, jint attrib_id) {
+ bt_status_t status;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->get_element_attribute_cmd((uint8_t)num_attrib,
+ (uint32_t)attrib_id))!= BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending getElementAttributeNative command, status: %d", status);
+ }
+}
+
+static void getPlayStatusNative(JNIEnv *env, jobject object) {
+ bt_status_t status;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->get_play_status_cmd())!= BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending getPlayStatusNative command, status: %d", status);
+ }
+}
+
+static void sendAbsVolRspNative(JNIEnv *env, jobject object, jint abs_vol) {
+ bt_status_t status;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->send_abs_vol_rsp((uint8_t)abs_vol))!= BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending sendAbsVolRspNative command, status: %d", status);
+ }
+}
+
+static void sendRegisterAbsVolRspNative(JNIEnv *env, jobject object, jbyte rsp_type, jint abs_vol) {
+ bt_status_t status;
+
+ if (!sBluetoothAvrcpInterface) return;
+
+ ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+ if ((status = sBluetoothAvrcpInterface->send_register_abs_vol_rsp((uint8_t)rsp_type,
+ (uint8_t)abs_vol))!= BT_STATUS_SUCCESS) {
+ ALOGE("Failed sending sendRegisterAbsVolRspNative command, status: %d", status);
+ }
+}
+
static JNINativeMethod sMethods[] = {
{"classInitNative", "()V", (void *) classInitNative},
{"initNative", "()V", (void *) initNative},
{"cleanupNative", "()V", (void *) cleanupNative},
- {"sendPassThroughCommandNative", "([BII)Z",
- (void *) sendPassThroughCommandNative},
+ {"sendPassThroughCommandNative", "([BII)Z",(void *) sendPassThroughCommandNative},
+ {"getCapabilitiesNative", "(I)V",(void *) getCapabilitiesNative},
+ {"listPlayerApplicationSettingAttributeNative", "()V",
+ (void *) listPlayerApplicationSettingAttributeNative},
+ {"listPlayerApplicationSettingValueNative", "(B)V",
+ (void *) listPlayerApplicationSettingValueNative},
+ {"getPlayerApplicationSettingValuesNative", "(B[B)V",
+ (void *) getPlayerApplicationSettingValuesNative},
+ {"setPlayerApplicationSettingValuesNative", "(B[B[B)V",
+ (void *) setPlayerApplicationSettingValuesNative},
+ {"registerNotificationNative", "(BI)V",
+ (void *) registerNotificationNative},
+ {"getElementAttributeNative", "(BI)V",(void *) getElementAttributeNative},
+ {"getPlayStatusNative", "()V",(void *) getPlayStatusNative},
+ {"sendAbsVolRspNative", "(I)V",(void *) sendAbsVolRspNative},
+ {"sendRegisterAbsVolRspNative", "(BI)V",(void *) sendRegisterAbsVolRspNative},
};
int register_com_android_bluetooth_avrcp_controller(JNIEnv* env)