16c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie/* 2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project 3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License"); 5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License. 6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at 7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * http://www.apache.org/licenses/LICENSE-2.0 9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software 11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS, 12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and 14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License. 156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie */ 16ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu 176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define LOG_TAG "BluetoothA2dpServiceJni" 186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define LOG_NDEBUG 0 206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "com_android_bluetooth.h" 226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "hardware/bt_av.h" 236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "utils/Log.h" 246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "android_runtime/AndroidRuntime.h" 256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include <string.h> 276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xienamespace android { 296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onConnectionStateChanged; 30ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamystatic jmethodID method_onAudioStateChanged; 316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic const btav_interface_t *sBluetoothA2dpInterface = NULL; 336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jobject mCallbacksObj = NULL; 346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic JNIEnv *sCallbackEnv = NULL; 356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic bool checkCallbackThread() { 3793f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy // Always fetch the latest callbackEnv from AdapterService. 3893f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy // Caching this could cause this sCallbackEnv to go out-of-sync 3993f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event 4093f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy // is received 4193f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy //if (sCallbackEnv == NULL) { 4293f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy sCallbackEnv = getCallbackEnv(); 4393f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy //} 446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie JNIEnv* env = AndroidRuntime::getJNIEnv(); 466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if (sCallbackEnv != env || sCallbackEnv == NULL) return false; 476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return true; 486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic void bta2dp_connection_state_callback(btav_connection_state_t state, bt_bdaddr_t* bd_addr) { 516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie jbyteArray addr; 526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 53c55a9837c004044051b71bb47182ace156691283Matthew Xie ALOGI("%s", __FUNCTION__); 546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if (!checkCallbackThread()) { \ 56c55a9837c004044051b71bb47182ace156691283Matthew Xie ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \ 576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return; \ 586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if (!addr) { 61c55a9837c004044051b71bb47182ace156691283Matthew Xie ALOGE("Fail to new jbyteArray bd addr for connection state"); 626c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return; 646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 666c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); 676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, (jint) state, 686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie addr); 696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie sCallbackEnv->DeleteLocalRef(addr); 716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 73ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamystatic void bta2dp_audio_state_callback(btav_audio_state_t state, bt_bdaddr_t* bd_addr) { 74ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy jbyteArray addr; 75ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy 76e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie ALOGI("%s", __FUNCTION__); 77ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy 78ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy if (!checkCallbackThread()) { \ 79e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \ 80ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy return; \ 81ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy } 82ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 83ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy if (!addr) { 84e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie ALOGE("Fail to new jbyteArray bd addr for connection state"); 85ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 86ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy return; 87ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy } 88ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy 89ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); 90ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, (jint) state, 91ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy addr); 92ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 93ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy sCallbackEnv->DeleteLocalRef(addr); 94ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy} 95ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy 966c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic btav_callbacks_t sBluetoothA2dpCallbacks = { 976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie sizeof(sBluetoothA2dpCallbacks), 986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie bta2dp_connection_state_callback, 9921f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panicker bta2dp_audio_state_callback, 10021f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panicker NULL, /* audio_config_cb */ 1016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}; 1026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1036c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic void classInitNative(JNIEnv* env, jclass clazz) { 1046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie method_onConnectionStateChanged = 1056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V"); 1066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 107ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy method_onAudioStateChanged = 108ac234ef0ddd67471d82f77c41535a5ea1b68b443Kausik Sinnaswamy env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V"); 1096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 110c55a9837c004044051b71bb47182ace156691283Matthew Xie ALOGI("%s: succeeds", __FUNCTION__); 1116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 1126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1136654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void initNative(JNIEnv *env, jobject object) { 1146654f5c903de510a70f9e72cd5ad7837b615d93ffredc const bt_interface_t* btInf; 1156654f5c903de510a70f9e72cd5ad7837b615d93ffredc bt_status_t status; 1166654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1176654f5c903de510a70f9e72cd5ad7837b615d93ffredc if ( (btInf = getBluetoothInterface()) == NULL) { 118e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie ALOGE("Bluetooth module is not loaded"); 1196654f5c903de510a70f9e72cd5ad7837b615d93ffredc return; 1206654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1216654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1226654f5c903de510a70f9e72cd5ad7837b615d93ffredc if (sBluetoothA2dpInterface !=NULL) { 123e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie ALOGW("Cleaning up A2DP Interface before initializing..."); 1246654f5c903de510a70f9e72cd5ad7837b615d93ffredc sBluetoothA2dpInterface->cleanup(); 1256654f5c903de510a70f9e72cd5ad7837b615d93ffredc sBluetoothA2dpInterface = NULL; 1266654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1276654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1286654f5c903de510a70f9e72cd5ad7837b615d93ffredc if (mCallbacksObj != NULL) { 129e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie ALOGW("Cleaning up A2DP callback object"); 1306654f5c903de510a70f9e72cd5ad7837b615d93ffredc env->DeleteGlobalRef(mCallbacksObj); 1316654f5c903de510a70f9e72cd5ad7837b615d93ffredc mCallbacksObj = NULL; 1326654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1336654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1346654f5c903de510a70f9e72cd5ad7837b615d93ffredc if ( (sBluetoothA2dpInterface = (btav_interface_t *) 1356654f5c903de510a70f9e72cd5ad7837b615d93ffredc btInf->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID)) == NULL) { 136e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie ALOGE("Failed to get Bluetooth A2DP Interface"); 1376654f5c903de510a70f9e72cd5ad7837b615d93ffredc return; 1386654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1396654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1406654f5c903de510a70f9e72cd5ad7837b615d93ffredc if ( (status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks)) != BT_STATUS_SUCCESS) { 141e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie ALOGE("Failed to initialize Bluetooth A2DP, status: %d", status); 1426654f5c903de510a70f9e72cd5ad7837b615d93ffredc sBluetoothA2dpInterface = NULL; 1436654f5c903de510a70f9e72cd5ad7837b615d93ffredc return; 1446654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1456654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie mCallbacksObj = env->NewGlobalRef(object); 1476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 1486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1496654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void cleanupNative(JNIEnv *env, jobject object) { 1506654f5c903de510a70f9e72cd5ad7837b615d93ffredc const bt_interface_t* btInf; 1516654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1526654f5c903de510a70f9e72cd5ad7837b615d93ffredc if ( (btInf = getBluetoothInterface()) == NULL) { 153e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie ALOGE("Bluetooth module is not loaded"); 1546654f5c903de510a70f9e72cd5ad7837b615d93ffredc return; 1556654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1566654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1576654f5c903de510a70f9e72cd5ad7837b615d93ffredc if (sBluetoothA2dpInterface !=NULL) { 1586654f5c903de510a70f9e72cd5ad7837b615d93ffredc sBluetoothA2dpInterface->cleanup(); 1596654f5c903de510a70f9e72cd5ad7837b615d93ffredc sBluetoothA2dpInterface = NULL; 1606654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1616654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1626654f5c903de510a70f9e72cd5ad7837b615d93ffredc if (mCallbacksObj != NULL) { 1636654f5c903de510a70f9e72cd5ad7837b615d93ffredc env->DeleteGlobalRef(mCallbacksObj); 1646654f5c903de510a70f9e72cd5ad7837b615d93ffredc mCallbacksObj = NULL; 1656654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1666654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 1676654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean connectA2dpNative(JNIEnv *env, jobject object, jbyteArray address) { 1696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie jbyte *addr; 1706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie bt_bdaddr_t * btAddr; 1716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie bt_status_t status; 1726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 173c55a9837c004044051b71bb47182ace156691283Matthew Xie ALOGI("%s: sBluetoothA2dpInterface: %p", __FUNCTION__, sBluetoothA2dpInterface); 1746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if (!sBluetoothA2dpInterface) return JNI_FALSE; 1756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie addr = env->GetByteArrayElements(address, NULL); 1776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie btAddr = (bt_bdaddr_t *) addr; 1786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if (!addr) { 1796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie jniThrowIOException(env, EINVAL); 1806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return JNI_FALSE; 1816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 1826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if ((status = sBluetoothA2dpInterface->connect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) { 184c55a9837c004044051b71bb47182ace156691283Matthew Xie ALOGE("Failed HF connection, status: %d", status); 1856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 1866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie env->ReleaseByteArrayElements(address, addr, 0); 1876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 1896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean disconnectA2dpNative(JNIEnv *env, jobject object, jbyteArray address) { 1916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie jbyte *addr; 1926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie bt_status_t status; 1936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if (!sBluetoothA2dpInterface) return JNI_FALSE; 1956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1966c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie addr = env->GetByteArrayElements(address, NULL); 1976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if (!addr) { 1986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie jniThrowIOException(env, EINVAL); 1996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return JNI_FALSE; 2006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if ( (status = sBluetoothA2dpInterface->disconnect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) { 203c55a9837c004044051b71bb47182ace156691283Matthew Xie ALOGE("Failed HF disconnection, status: %d", status); 2046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie env->ReleaseByteArrayElements(address, addr, 0); 2066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 2076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 2086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic JNINativeMethod sMethods[] = { 2106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie {"classInitNative", "()V", (void *) classInitNative}, 2116654f5c903de510a70f9e72cd5ad7837b615d93ffredc {"initNative", "()V", (void *) initNative}, 2126654f5c903de510a70f9e72cd5ad7837b615d93ffredc {"cleanupNative", "()V", (void *) cleanupNative}, 2136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie {"connectA2dpNative", "([B)Z", (void *) connectA2dpNative}, 2146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie {"disconnectA2dpNative", "([B)Z", (void *) disconnectA2dpNative}, 2156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}; 2166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieint register_com_android_bluetooth_a2dp(JNIEnv* env) 2186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie{ 21921f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panicker return jniRegisterNativeMethods(env, "com/android/bluetooth/a2dp/A2dpStateMachine", 2206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie sMethods, NELEM(sMethods)); 2216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 2226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 224