com_android_bluetooth_avrcp.cpp revision 5c86abdc7875a8fae28c57e3e36a0a8eaae5cb04
1c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu/* 2c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * Copyright (C) 2012 The Android Open Source Project 3c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * 4c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License"); 5c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * you may not use this file except in compliance with the License. 6c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * You may obtain a copy of the License at 7c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * 8c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * http://www.apache.org/licenses/LICENSE-2.0 9c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * 10c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * Unless required by applicable law or agreed to in writing, software 11c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS, 12c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * See the License for the specific language governing permissions and 14c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * limitations under the License. 15c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu */ 16c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 17c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#define LOG_TAG "BluetoothAvrcpServiceJni" 18c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 19c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#define LOG_NDEBUG 0 20c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 21c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include "com_android_bluetooth.h" 22c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include "hardware/bt_rc.h" 23c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include "utils/Log.h" 24c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include "android_runtime/AndroidRuntime.h" 25c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 26c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include <string.h> 27c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 28c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xunamespace android { 2917675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic jmethodID method_getRcFeatures; 30c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jmethodID method_getPlayStatus; 31c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jmethodID method_getElementAttr; 32c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jmethodID method_registerNotification; 3317675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic jmethodID method_volumeChangeCallback; 34ace834feb02adabd61f628c4471147aea02d939cJohn Dustatic jmethodID method_handlePassthroughCmd; 355c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Guptastatic jmethodID method_handlePassthroughRsp; 365c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Guptastatic jmethodID method_onConnectionStateChanged; 37c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 38c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic const btrc_interface_t *sBluetoothAvrcpInterface = NULL; 39c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jobject mCallbacksObj = NULL; 40c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic JNIEnv *sCallbackEnv = NULL; 41c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 42c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic bool checkCallbackThread() { 43c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu // Always fetch the latest callbackEnv from AdapterService. 44c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu // Caching this could cause this sCallbackEnv to go out-of-sync 45c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event 46c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu // is received 47c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sCallbackEnv = getCallbackEnv(); 48c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 49c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu JNIEnv* env = AndroidRuntime::getJNIEnv(); 50c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (sCallbackEnv != env || sCallbackEnv == NULL) return false; 51c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return true; 52c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 53c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 5417675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic void btavrcp_remote_features_callback(bt_bdaddr_t* bd_addr, btrc_remote_features_t features) { 5517675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGI("%s", __FUNCTION__); 5617675906064bb72fdcca75baa56cdf8bb8968d01John Du jbyteArray addr; 5717675906064bb72fdcca75baa56cdf8bb8968d01John Du 5817675906064bb72fdcca75baa56cdf8bb8968d01John Du if (!checkCallbackThread()) { 5917675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 6017675906064bb72fdcca75baa56cdf8bb8968d01John Du return; 6117675906064bb72fdcca75baa56cdf8bb8968d01John Du } 6217675906064bb72fdcca75baa56cdf8bb8968d01John Du addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 6317675906064bb72fdcca75baa56cdf8bb8968d01John Du if (!addr) { 6417675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGE("Fail to new jbyteArray bd addr for connection state"); 6517675906064bb72fdcca75baa56cdf8bb8968d01John Du checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 6617675906064bb72fdcca75baa56cdf8bb8968d01John Du return; 6717675906064bb72fdcca75baa56cdf8bb8968d01John Du } 6817675906064bb72fdcca75baa56cdf8bb8968d01John Du 6917675906064bb72fdcca75baa56cdf8bb8968d01John Du sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); 7017675906064bb72fdcca75baa56cdf8bb8968d01John Du sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getRcFeatures, addr, (jint)features); 7117675906064bb72fdcca75baa56cdf8bb8968d01John Du checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 72fd80b9517bf8bc45257af83074114d493ba7d984Nitin Srivastava sCallbackEnv->DeleteLocalRef(addr); 7317675906064bb72fdcca75baa56cdf8bb8968d01John Du} 7417675906064bb72fdcca75baa56cdf8bb8968d01John Du 75c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void btavrcp_get_play_status_callback() { 76c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s", __FUNCTION__); 77c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 78c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!checkCallbackThread()) { 79c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 80c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 81c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 82c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 83c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getPlayStatus); 84c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 85c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 86c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 87c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void btavrcp_get_element_attr_callback(uint8_t num_attr, btrc_media_attr_t *p_attrs) { 88c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jintArray attrs; 89c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 90c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s", __FUNCTION__); 91c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 92c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!checkCallbackThread()) { 93c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 94c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 95c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 96c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu attrs = (jintArray)sCallbackEnv->NewIntArray(num_attr); 97c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!attrs) { 98c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Fail to new jintArray for attrs"); 99c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 100c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 101c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 102c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sCallbackEnv->SetIntArrayRegion(attrs, 0, num_attr, (jint *)p_attrs); 103c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getElementAttr, (jbyte)num_attr, attrs); 104c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 105c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sCallbackEnv->DeleteLocalRef(attrs); 106c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 107c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 108c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void btavrcp_register_notification_callback(btrc_event_id_t event_id, uint32_t param) { 109c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s", __FUNCTION__); 110c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 111c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!checkCallbackThread()) { 112c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 113c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 114c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 115c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 116c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sCallbackEnv->CallVoidMethod(mCallbacksObj, method_registerNotification, 117c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (jint)event_id, (jint)param); 118c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 119c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 120c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 12117675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic void btavrcp_volume_change_callback(uint8_t volume, uint8_t ctype) { 12217675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGI("%s", __FUNCTION__); 12317675906064bb72fdcca75baa56cdf8bb8968d01John Du 12417675906064bb72fdcca75baa56cdf8bb8968d01John Du if (!checkCallbackThread()) { 12517675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 12617675906064bb72fdcca75baa56cdf8bb8968d01John Du return; 12717675906064bb72fdcca75baa56cdf8bb8968d01John Du } 12817675906064bb72fdcca75baa56cdf8bb8968d01John Du 12917675906064bb72fdcca75baa56cdf8bb8968d01John Du sCallbackEnv->CallVoidMethod(mCallbacksObj, method_volumeChangeCallback, (jint)volume, 13017675906064bb72fdcca75baa56cdf8bb8968d01John Du (jint)ctype); 13117675906064bb72fdcca75baa56cdf8bb8968d01John Du checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 13217675906064bb72fdcca75baa56cdf8bb8968d01John Du} 13317675906064bb72fdcca75baa56cdf8bb8968d01John Du 134ace834feb02adabd61f628c4471147aea02d939cJohn Dustatic void btavrcp_passthrough_command_callback(int id, int pressed) { 135ace834feb02adabd61f628c4471147aea02d939cJohn Du ALOGI("%s", __FUNCTION__); 136ace834feb02adabd61f628c4471147aea02d939cJohn Du 137ace834feb02adabd61f628c4471147aea02d939cJohn Du if (!checkCallbackThread()) { 138ace834feb02adabd61f628c4471147aea02d939cJohn Du ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 139ace834feb02adabd61f628c4471147aea02d939cJohn Du return; 140ace834feb02adabd61f628c4471147aea02d939cJohn Du } 141ace834feb02adabd61f628c4471147aea02d939cJohn Du 142ace834feb02adabd61f628c4471147aea02d939cJohn Du sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handlePassthroughCmd, (jint)id, 143ace834feb02adabd61f628c4471147aea02d939cJohn Du (jint)pressed); 144ace834feb02adabd61f628c4471147aea02d939cJohn Du checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 145ace834feb02adabd61f628c4471147aea02d939cJohn Du} 146ace834feb02adabd61f628c4471147aea02d939cJohn Du 1475c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Guptastatic void btavrcp_passthrough_response_callback(int id, int pressed) { 1485c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGI("%s", __FUNCTION__); 1495c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGI("id: %d, pressed: %d", id, pressed); 1505c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 1515c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta if (!checkCallbackThread()) { 1525c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 1535c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta return; 1545c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta } 1555c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 1565c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handlePassthroughRsp, (jint)id, 1575c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta (jint)pressed); 1585c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 1595c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta} 1605c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 1615c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Guptastatic void btavrcp_connection_state_callback(int state, bt_bdaddr_t* bd_addr) { 1625c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta jbyteArray addr; 1635c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 1645c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGI("%s", __FUNCTION__); 1655c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGI("conn state: %d", state); 1665c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 1675c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta if (!checkCallbackThread()) { \ 1685c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \ 1695c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta return; \ 1705c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta } 1715c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 1725c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 1735c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta if (!addr) { 1745c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGE("Fail to new jbyteArray bd addr for connection state"); 1755c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 1765c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta return; 1775c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta } 1785c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 1795c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); 1805c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, (jint) state, 1815c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta addr); 1825c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 1835c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta sCallbackEnv->DeleteLocalRef(addr); 1845c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta} 1855c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 1865c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 187c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic btrc_callbacks_t sBluetoothAvrcpCallbacks = { 188c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sizeof(sBluetoothAvrcpCallbacks), 18917675906064bb72fdcca75baa56cdf8bb8968d01John Du btavrcp_remote_features_callback, 190c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btavrcp_get_play_status_callback, 191c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 192c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 193c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 194c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 195c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 196c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 197c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btavrcp_get_element_attr_callback, 198ace834feb02adabd61f628c4471147aea02d939cJohn Du btavrcp_register_notification_callback, 19917675906064bb72fdcca75baa56cdf8bb8968d01John Du btavrcp_volume_change_callback, 2005c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta btavrcp_passthrough_command_callback, 2015c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta btavrcp_passthrough_response_callback, 2025c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta btavrcp_connection_state_callback 203c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu}; 204c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 205c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void classInitNative(JNIEnv* env, jclass clazz) { 20617675906064bb72fdcca75baa56cdf8bb8968d01John Du method_getRcFeatures = 20717675906064bb72fdcca75baa56cdf8bb8968d01John Du env->GetMethodID(clazz, "getRcFeatures", "([BI)V"); 208c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu method_getPlayStatus = 209c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->GetMethodID(clazz, "getPlayStatus", "()V"); 210c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 211c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu method_getElementAttr = 212c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->GetMethodID(clazz, "getElementAttr", "(B[I)V"); 213c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 214c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu method_registerNotification = 215c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->GetMethodID(clazz, "registerNotification", "(II)V"); 216c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 21717675906064bb72fdcca75baa56cdf8bb8968d01John Du method_volumeChangeCallback = 21817675906064bb72fdcca75baa56cdf8bb8968d01John Du env->GetMethodID(clazz, "volumeChangeCallback", "(II)V"); 21917675906064bb72fdcca75baa56cdf8bb8968d01John Du 220ace834feb02adabd61f628c4471147aea02d939cJohn Du method_handlePassthroughCmd = 221ace834feb02adabd61f628c4471147aea02d939cJohn Du env->GetMethodID(clazz, "handlePassthroughCmd", "(II)V"); 222ace834feb02adabd61f628c4471147aea02d939cJohn Du 2235c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta method_handlePassthroughRsp = 2245c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta env->GetMethodID(clazz, "handlePassthroughRsp", "(II)V"); 2255c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 2265c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta method_onConnectionStateChanged = 2275c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V"); 2285c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 229c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s: succeeds", __FUNCTION__); 230c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 231c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 232c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void initNative(JNIEnv *env, jobject object) { 233c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu const bt_interface_t* btInf; 234c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 235c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 236c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ( (btInf = getBluetoothInterface()) == NULL) { 237c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Bluetooth module is not loaded"); 238c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 239c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 240c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 241c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (sBluetoothAvrcpInterface !=NULL) { 242c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGW("Cleaning up Avrcp Interface before initializing..."); 243c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface->cleanup(); 244c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface = NULL; 245c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 246c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 247c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (mCallbacksObj != NULL) { 248c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGW("Cleaning up Avrcp callback object"); 249c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->DeleteGlobalRef(mCallbacksObj); 250c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mCallbacksObj = NULL; 251c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 252c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 253c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ( (sBluetoothAvrcpInterface = (btrc_interface_t *) 254c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btInf->get_profile_interface(BT_PROFILE_AV_RC_ID)) == NULL) { 255c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed to get Bluetooth Avrcp Interface"); 256c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 257c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 258c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 259c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ( (status = sBluetoothAvrcpInterface->init(&sBluetoothAvrcpCallbacks)) != 260c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu BT_STATUS_SUCCESS) { 261c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed to initialize Bluetooth Avrcp, status: %d", status); 262c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface = NULL; 263c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 264c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 265c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 266c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mCallbacksObj = env->NewGlobalRef(object); 267c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 268c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 269c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void cleanupNative(JNIEnv *env, jobject object) { 270c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu const bt_interface_t* btInf; 271c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 272c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ( (btInf = getBluetoothInterface()) == NULL) { 273c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Bluetooth module is not loaded"); 274c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 275c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 276c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 277c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (sBluetoothAvrcpInterface !=NULL) { 278c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface->cleanup(); 279c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface = NULL; 280c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 281c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 282c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (mCallbacksObj != NULL) { 283c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->DeleteGlobalRef(mCallbacksObj); 284c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mCallbacksObj = NULL; 285c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 286c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 287c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 288c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jboolean getPlayStatusRspNative(JNIEnv *env, jobject object, jint playStatus, 289c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jint songLen, jint songPos) { 290c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 291c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 292c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 293c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 294c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 295c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ((status = sBluetoothAvrcpInterface->get_play_status_rsp((btrc_play_status_t)playStatus, 296c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu songLen, songPos)) != BT_STATUS_SUCCESS) { 297c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed get_play_status_rsp, status: %d", status); 298c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 299c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 300c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 301c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 302c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 303c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu static jboolean getElementAttrRspNative(JNIEnv *env, jobject object, jbyte numAttr, 304c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jintArray attrIds, jobjectArray textArray) { 305c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jint *attr; 306c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 307c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jstring text; 308c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu int i; 309c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btrc_element_attr_val_t *pAttrs = NULL; 310c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu const char* textStr; 311c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 312c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 313c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 314c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (numAttr > BTRC_MAX_ELEM_ATTR_SIZE) { 315c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("get_element_attr_rsp: number of attributes exceed maximum"); 316c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 317c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 318c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 319c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu pAttrs = new btrc_element_attr_val_t[numAttr]; 320c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!pAttrs) { 321c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("get_element_attr_rsp: not have enough memeory"); 322c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 323c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 324c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 325c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu attr = env->GetIntArrayElements(attrIds, NULL); 326c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!attr) { 327c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu delete[] pAttrs; 328c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jniThrowIOException(env, EINVAL); 329c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 330c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 331c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 332c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu for (i = 0; i < numAttr; ++i) { 333c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu text = (jstring) env->GetObjectArrayElement(textArray, i); 334c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu textStr = env->GetStringUTFChars(text, NULL); 335c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!textStr) { 336c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("get_element_attr_rsp: GetStringUTFChars return NULL"); 337c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->DeleteLocalRef(text); 338c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu break; 339c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 340885213461ae72d6db178c95fafc01cde153230dbZhihai Xu 341885213461ae72d6db178c95fafc01cde153230dbZhihai Xu pAttrs[i].attr_id = attr[i]; 342c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (strlen(textStr) >= BTRC_MAX_ATTR_STR_LEN) { 343c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("get_element_attr_rsp: string length exceed maximum"); 344885213461ae72d6db178c95fafc01cde153230dbZhihai Xu strncpy((char *)pAttrs[i].text, textStr, BTRC_MAX_ATTR_STR_LEN-1); 345885213461ae72d6db178c95fafc01cde153230dbZhihai Xu pAttrs[i].text[BTRC_MAX_ATTR_STR_LEN-1] = 0; 346885213461ae72d6db178c95fafc01cde153230dbZhihai Xu } else { 347885213461ae72d6db178c95fafc01cde153230dbZhihai Xu strcpy((char *)pAttrs[i].text, textStr); 348c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 349c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->ReleaseStringUTFChars(text, textStr); 350c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->DeleteLocalRef(text); 351c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 352c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 353c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (i < numAttr) { 354c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu delete[] pAttrs; 355c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->ReleaseIntArrayElements(attrIds, attr, 0); 356c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 357c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 358c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 359c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ((status = sBluetoothAvrcpInterface->get_element_attr_rsp(numAttr, pAttrs)) != 360c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu BT_STATUS_SUCCESS) { 361c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed get_element_attr_rsp, status: %d", status); 362c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 363c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 364c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu delete[] pAttrs; 365c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->ReleaseIntArrayElements(attrIds, attr, 0); 366c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 367c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 368c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 369c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jboolean registerNotificationRspPlayStatusNative(JNIEnv *env, jobject object, 370c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jint type, jint playStatus) { 371c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 372c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btrc_register_notification_t param; 373c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 374c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 375c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 376c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 377c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu param.play_status = (btrc_play_status_t)playStatus; 378c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ((status = sBluetoothAvrcpInterface->register_notification_rsp(BTRC_EVT_PLAY_STATUS_CHANGED, 379c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (btrc_notification_type_t)type, ¶m)) != BT_STATUS_SUCCESS) { 380c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed register_notification_rsp play status, status: %d", status); 381c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 382c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 383c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 384c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 385c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 386c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jboolean registerNotificationRspTrackChangeNative(JNIEnv *env, jobject object, 387c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jint type, jbyteArray track) { 388c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 389c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btrc_register_notification_t param; 390c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jbyte *trk; 391c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu int i; 392c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 393c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 394c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 395c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 396c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu trk = env->GetByteArrayElements(track, NULL); 397c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!trk) { 398c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jniThrowIOException(env, EINVAL); 399c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 400c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 401c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 402c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu for (i = 0; i < BTRC_UID_SIZE; ++i) { 403c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu param.track[i] = trk[i]; 404c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 405c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 406c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ((status = sBluetoothAvrcpInterface->register_notification_rsp(BTRC_EVT_TRACK_CHANGE, 407c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (btrc_notification_type_t)type, ¶m)) != BT_STATUS_SUCCESS) { 408c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed register_notification_rsp track change, status: %d", status); 409c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 410c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 411c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->ReleaseByteArrayElements(track, trk, 0); 412c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 413c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 414c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 415aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xustatic jboolean registerNotificationRspPlayPosNative(JNIEnv *env, jobject object, 416aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu jint type, jint playPos) { 417aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu bt_status_t status; 418aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu btrc_register_notification_t param; 419aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 420aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 421aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 422aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 423aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu param.song_pos = (uint32_t)playPos; 424aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu if ((status = sBluetoothAvrcpInterface->register_notification_rsp(BTRC_EVT_PLAY_POS_CHANGED, 425aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu (btrc_notification_type_t)type, ¶m)) != BT_STATUS_SUCCESS) { 426aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu ALOGE("Failed register_notification_rsp play position, status: %d", status); 427aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu } 428aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 429aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 430aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu} 431aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 43217675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic jboolean setVolumeNative(JNIEnv *env, jobject object, jint volume) { 43317675906064bb72fdcca75baa56cdf8bb8968d01John Du bt_status_t status; 43417675906064bb72fdcca75baa56cdf8bb8968d01John Du 43517675906064bb72fdcca75baa56cdf8bb8968d01John Du //TODO: delete test code 43617675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGI("%s: jint: %d, uint8_t: %u", __FUNCTION__, volume, (uint8_t) volume); 43717675906064bb72fdcca75baa56cdf8bb8968d01John Du 43817675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 43917675906064bb72fdcca75baa56cdf8bb8968d01John Du if (!sBluetoothAvrcpInterface) return JNI_FALSE; 44017675906064bb72fdcca75baa56cdf8bb8968d01John Du 44117675906064bb72fdcca75baa56cdf8bb8968d01John Du if ((status = sBluetoothAvrcpInterface->set_volume((uint8_t)volume)) != BT_STATUS_SUCCESS) { 44217675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGE("Failed set_volume, status: %d", status); 44317675906064bb72fdcca75baa56cdf8bb8968d01John Du } 44417675906064bb72fdcca75baa56cdf8bb8968d01John Du 44517675906064bb72fdcca75baa56cdf8bb8968d01John Du return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 44617675906064bb72fdcca75baa56cdf8bb8968d01John Du} 44717675906064bb72fdcca75baa56cdf8bb8968d01John Du 4485c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Guptastatic jboolean sendPassThroughCommandNative(JNIEnv *env, jobject object, 4495c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta jint key_code, jint key_state) { 4505c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta bt_status_t status; 4515c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 4525c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta if (!sBluetoothAvrcpInterface) return JNI_FALSE; 4535c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 4545c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 4555c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 4565c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGI("key_code: %d, key_state: %d", key_code, key_state); 4575c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 4585c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta if ((status = sBluetoothAvrcpInterface->send_pass_through_cmd((uint8_t)key_code, 4595c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta (uint8_t)key_state))!= BT_STATUS_SUCCESS) { 4605c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta ALOGE("Failed sending passthru command, status: %d", status); 4615c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta } 4625c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 4635c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 4645c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta} 4655c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 466c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic JNINativeMethod sMethods[] = { 467c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"classInitNative", "()V", (void *) classInitNative}, 468c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"initNative", "()V", (void *) initNative}, 469c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"cleanupNative", "()V", (void *) cleanupNative}, 470c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"getPlayStatusRspNative", "(III)Z", (void *) getPlayStatusRspNative}, 471c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"getElementAttrRspNative", "(B[I[Ljava/lang/String;)Z", (void *) getElementAttrRspNative}, 472c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"registerNotificationRspPlayStatusNative", "(II)Z", 473c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (void *) registerNotificationRspPlayStatusNative}, 474c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"registerNotificationRspTrackChangeNative", "(I[B)Z", 475c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (void *) registerNotificationRspTrackChangeNative}, 476aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu {"registerNotificationRspPlayPosNative", "(II)Z", 477aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu (void *) registerNotificationRspPlayPosNative}, 47817675906064bb72fdcca75baa56cdf8bb8968d01John Du {"setVolumeNative", "(I)Z", 4795c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta (void *) setVolumeNative}, 4805c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta {"sendPassThroughCommandNative", "(II)Z", 4815c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta (void *) sendPassThroughCommandNative}, 482c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu}; 483c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 484c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuint register_com_android_bluetooth_avrcp(JNIEnv* env) 485c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu{ 486c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return jniRegisterNativeMethods(env, "com/android/bluetooth/a2dp/Avrcp", 487c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sMethods, NELEM(sMethods)); 488c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 489c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 490c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 491