diff options
author | AnubhavGupta <anubhavg@codeaurora.org> | 2015-02-27 19:08:36 +0530 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2015-10-06 03:25:43 -0600 |
commit | 442962cde4c933ba91eeeb422e48d063fa5fa0fb (patch) | |
tree | d8d1d124172a0675397899fc42f0daf211f13d0a /jni/com_android_bluetooth_avrcp_controller.cpp | |
parent | db525f6a5d47ea8934dd58cffff452da89489f30 (diff) | |
download | android_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.cpp | 558 |
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) |