com_android_bluetooth_btservice_AdapterService.cpp revision cf27f0ddf906a8f76a22b8a30ff4262526e33477
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "BluetoothServiceJni" 18#include "android_runtime/AndroidRuntime.h" 19#include "android_runtime/Log.h" 20#include "com_android_bluetooth.h" 21#include "cutils/properties.h" 22#include "hardware/bt_sock.h" 23#include "utils/Log.h" 24#include "utils/misc.h" 25 26#include <pthread.h> 27#include <string.h> 28 29#include <fcntl.h> 30#include <sys/stat.h> 31 32namespace android { 33// OOB_LE_BD_ADDR_SIZE is 6 bytes addres + 1 byte address type 34#define OOB_LE_BD_ADDR_SIZE 7 35#define OOB_TK_SIZE 16 36#define OOB_LE_SC_C_SIZE 16 37#define OOB_LE_SC_R_SIZE 16 38 39#define ADDITIONAL_NREFS 50 40static jmethodID method_stateChangeCallback; 41static jmethodID method_adapterPropertyChangedCallback; 42static jmethodID method_devicePropertyChangedCallback; 43static jmethodID method_deviceFoundCallback; 44static jmethodID method_pinRequestCallback; 45static jmethodID method_sspRequestCallback; 46static jmethodID method_bondStateChangeCallback; 47static jmethodID method_aclStateChangeCallback; 48static jmethodID method_discoveryStateChangeCallback; 49static jmethodID method_setWakeAlarm; 50static jmethodID method_acquireWakeLock; 51static jmethodID method_releaseWakeLock; 52static jmethodID method_energyInfo; 53 54static struct { 55 jclass clazz; 56 jmethodID constructor; 57} android_bluetooth_UidTraffic; 58 59static const bt_interface_t* sBluetoothInterface = NULL; 60static const btsock_interface_t* sBluetoothSocketInterface = NULL; 61static JNIEnv* callbackEnv = NULL; 62 63static jobject sJniAdapterServiceObj; 64static jobject sJniCallbacksObj; 65static jfieldID sJniCallbacksField; 66 67const bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; } 68 69JNIEnv* getCallbackEnv() { return callbackEnv; } 70 71static void adapter_state_change_callback(bt_state_t status) { 72 CallbackEnv sCallbackEnv(__func__); 73 if (!sCallbackEnv.valid()) return; 74 ALOGV("%s: Status is: %d", __func__, status); 75 76 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, 77 (jint)status); 78} 79 80static int get_properties(int num_properties, bt_property_t* properties, 81 jintArray* types, jobjectArray* props) { 82 jbyteArray propVal; 83 for (int i = 0; i < num_properties; i++) { 84 propVal = callbackEnv->NewByteArray(properties[i].len); 85 if (propVal == NULL) goto Fail; 86 87 callbackEnv->SetByteArrayRegion(propVal, 0, properties[i].len, 88 (jbyte*)properties[i].val); 89 callbackEnv->SetObjectArrayElement(*props, i, propVal); 90 // Delete reference to propVal 91 callbackEnv->DeleteLocalRef(propVal); 92 callbackEnv->SetIntArrayRegion(*types, i, 1, (jint*)&properties[i].type); 93 } 94 return 0; 95Fail: 96 if (propVal) callbackEnv->DeleteLocalRef(propVal); 97 ALOGE("Error while allocation of array in %s", __func__); 98 return -1; 99} 100 101static void adapter_properties_callback(bt_status_t status, int num_properties, 102 bt_property_t* properties) { 103 CallbackEnv sCallbackEnv(__func__); 104 if (!sCallbackEnv.valid()) return; 105 106 ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties); 107 108 if (status != BT_STATUS_SUCCESS) { 109 ALOGE("%s: Status %d is incorrect", __func__, status); 110 return; 111 } 112 113 jbyteArray val = (jbyteArray)sCallbackEnv->NewByteArray(num_properties); 114 if (val == NULL) { 115 ALOGE("%s: Error allocating byteArray", __func__); 116 return; 117 } 118 119 jclass mclass = sCallbackEnv->GetObjectClass(val); 120 121 /* (BT) Initialize the jobjectArray and jintArray here itself and send the 122 initialized array pointers alone to get_properties */ 123 124 jobjectArray props = 125 sCallbackEnv->NewObjectArray(num_properties, mclass, NULL); 126 if (props == NULL) { 127 ALOGE("%s: Error allocating object Array for properties", __func__); 128 return; 129 } 130 131 jintArray types = (jintArray)sCallbackEnv->NewIntArray(num_properties); 132 if (types == NULL) { 133 ALOGE("%s: Error allocating int Array for values", __func__); 134 return; 135 } 136 // Delete the reference to val and mclass 137 sCallbackEnv->DeleteLocalRef(mclass); 138 sCallbackEnv->DeleteLocalRef(val); 139 140 if (get_properties(num_properties, properties, &types, &props) < 0) { 141 if (props) sCallbackEnv->DeleteLocalRef(props); 142 if (types) sCallbackEnv->DeleteLocalRef(types); 143 return; 144 } 145 146 sCallbackEnv->CallVoidMethod( 147 sJniCallbacksObj, method_adapterPropertyChangedCallback, types, props); 148 sCallbackEnv->DeleteLocalRef(props); 149 sCallbackEnv->DeleteLocalRef(types); 150} 151 152static void remote_device_properties_callback(bt_status_t status, 153 bt_bdaddr_t* bd_addr, 154 int num_properties, 155 bt_property_t* properties) { 156 CallbackEnv sCallbackEnv(__func__); 157 if (!sCallbackEnv.valid()) return; 158 159 ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties); 160 161 if (status != BT_STATUS_SUCCESS) { 162 ALOGE("%s: Status %d is incorrect", __func__, status); 163 return; 164 } 165 166 sCallbackEnv->PushLocalFrame(ADDITIONAL_NREFS); 167 168 jbyteArray val = (jbyteArray)sCallbackEnv->NewByteArray(num_properties); 169 if (val == NULL) { 170 ALOGE("%s: Error allocating byteArray", __func__); 171 return; 172 } 173 174 jclass mclass = sCallbackEnv->GetObjectClass(val); 175 176 /* Initialize the jobjectArray and jintArray here itself and send the 177 initialized array pointers alone to get_properties */ 178 179 jobjectArray props = 180 sCallbackEnv->NewObjectArray(num_properties, mclass, NULL); 181 if (props == NULL) { 182 ALOGE("%s: Error allocating object Array for properties", __func__); 183 return; 184 } 185 186 jintArray types = (jintArray)sCallbackEnv->NewIntArray(num_properties); 187 if (types == NULL) { 188 ALOGE("%s: Error allocating int Array for values", __func__); 189 return; 190 } 191 // Delete the reference to val and mclass 192 sCallbackEnv->DeleteLocalRef(mclass); 193 sCallbackEnv->DeleteLocalRef(val); 194 195 jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 196 if (addr == NULL) { 197 ALOGE("Error while allocation byte array in %s", __func__); 198 return; 199 } 200 201 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), 202 (jbyte*)bd_addr); 203 204 if (get_properties(num_properties, properties, &types, &props) < 0) { 205 if (props) sCallbackEnv->DeleteLocalRef(props); 206 if (types) sCallbackEnv->DeleteLocalRef(types); 207 sCallbackEnv->PopLocalFrame(NULL); 208 return; 209 } 210 211 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, 212 method_devicePropertyChangedCallback, addr, 213 types, props); 214 sCallbackEnv->DeleteLocalRef(props); 215 sCallbackEnv->DeleteLocalRef(types); 216 sCallbackEnv->DeleteLocalRef(addr); 217 sCallbackEnv->PopLocalFrame(NULL); 218} 219 220static void device_found_callback(int num_properties, 221 bt_property_t* properties) { 222 CallbackEnv sCallbackEnv(__func__); 223 if (!sCallbackEnv.valid()) return; 224 225 jbyteArray addr = NULL; 226 int addr_index; 227 for (int i = 0; i < num_properties; i++) { 228 if (properties[i].type == BT_PROPERTY_BDADDR) { 229 addr = sCallbackEnv->NewByteArray(properties[i].len); 230 if (addr) { 231 sCallbackEnv->SetByteArrayRegion(addr, 0, properties[i].len, 232 (jbyte*)properties[i].val); 233 addr_index = i; 234 } else { 235 ALOGE("Address is NULL (unable to allocate) in %s", __func__); 236 return; 237 } 238 } 239 } 240 if (addr == NULL) { 241 ALOGE("Address is NULL in %s", __func__); 242 return; 243 } 244 245 ALOGV("%s: Properties: %d, Address: %s", __func__, num_properties, 246 (const char*)properties[addr_index].val); 247 248 remote_device_properties_callback(BT_STATUS_SUCCESS, 249 (bt_bdaddr_t*)properties[addr_index].val, 250 num_properties, properties); 251 252 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, 253 addr); 254 sCallbackEnv->DeleteLocalRef(addr); 255} 256 257static void bond_state_changed_callback(bt_status_t status, 258 bt_bdaddr_t* bd_addr, 259 bt_bond_state_t state) { 260 CallbackEnv sCallbackEnv(__func__); 261 if (!sCallbackEnv.valid()) return; 262 263 if (!bd_addr) { 264 ALOGE("Address is null in %s", __func__); 265 return; 266 } 267 268 jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 269 if (addr == NULL) { 270 ALOGE("Address allocation failed in %s", __func__); 271 return; 272 } 273 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), 274 (jbyte*)bd_addr); 275 276 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, 277 (jint)status, addr, (jint)state); 278 sCallbackEnv->DeleteLocalRef(addr); 279} 280 281static void acl_state_changed_callback(bt_status_t status, bt_bdaddr_t* bd_addr, 282 bt_acl_state_t state) { 283 if (!bd_addr) { 284 ALOGE("Address is null in %s", __func__); 285 return; 286 } 287 288 CallbackEnv sCallbackEnv(__func__); 289 if (!sCallbackEnv.valid()) return; 290 291 jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 292 if (addr == NULL) { 293 ALOGE("Address allocation failed in %s", __func__); 294 return; 295 } 296 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), 297 (jbyte*)bd_addr); 298 299 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, 300 (jint)status, addr, (jint)state); 301 sCallbackEnv->DeleteLocalRef(addr); 302} 303 304static void discovery_state_changed_callback(bt_discovery_state_t state) { 305 CallbackEnv sCallbackEnv(__func__); 306 if (!sCallbackEnv.valid()) return; 307 308 ALOGV("%s: DiscoveryState:%d ", __func__, state); 309 310 sCallbackEnv->CallVoidMethod( 311 sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state); 312} 313 314static void pin_request_callback(bt_bdaddr_t* bd_addr, bt_bdname_t* bdname, 315 uint32_t cod, bool min_16_digits) { 316 if (!bd_addr) { 317 ALOGE("Address is null in %s", __func__); 318 return; 319 } 320 321 CallbackEnv sCallbackEnv(__func__); 322 if (!sCallbackEnv.valid()) return; 323 324 jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 325 if (addr == NULL) { 326 ALOGE("Error while allocating in: %s", __func__); 327 return; 328 } 329 330 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), 331 (jbyte*)bd_addr); 332 333 jbyteArray devname = sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)); 334 if (devname == NULL) { 335 ALOGE("Error while allocating in: %s", __func__); 336 sCallbackEnv->DeleteLocalRef(addr); 337 return; 338 } 339 340 sCallbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), 341 (jbyte*)bdname); 342 343 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, 344 addr, devname, cod, min_16_digits); 345 sCallbackEnv->DeleteLocalRef(addr); 346 sCallbackEnv->DeleteLocalRef(devname); 347} 348 349static void ssp_request_callback(bt_bdaddr_t* bd_addr, bt_bdname_t* bdname, 350 uint32_t cod, bt_ssp_variant_t pairing_variant, 351 uint32_t pass_key) { 352 if (!bd_addr) { 353 ALOGE("Address is null in %s", __func__); 354 return; 355 } 356 CallbackEnv sCallbackEnv(__func__); 357 if (!sCallbackEnv.valid()) return; 358 359 jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 360 if (addr == NULL) { 361 ALOGE("Error while allocating in: %s", __func__); 362 return; 363 } 364 365 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), 366 (jbyte*)bd_addr); 367 368 jbyteArray devname = sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)); 369 if (devname == NULL) { 370 sCallbackEnv->DeleteLocalRef(addr); 371 ALOGE("Error while allocating in: %s", __func__); 372 return; 373 } 374 375 sCallbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), 376 (jbyte*)bdname); 377 378 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, 379 addr, devname, cod, (jint)pairing_variant, 380 pass_key); 381 382 sCallbackEnv->DeleteLocalRef(addr); 383 sCallbackEnv->DeleteLocalRef(devname); 384} 385 386static void callback_thread_event(bt_cb_thread_evt event) { 387 JavaVM* vm = AndroidRuntime::getJavaVM(); 388 if (event == ASSOCIATE_JVM) { 389 JavaVMAttachArgs args; 390 char name[] = "BT Service Callback Thread"; 391 args.version = JNI_VERSION_1_6; 392 args.name = name; 393 args.group = NULL; 394 vm->AttachCurrentThread(&callbackEnv, &args); 395 ALOGV("Callback thread attached: %p", callbackEnv); 396 } else if (event == DISASSOCIATE_JVM) { 397 if (callbackEnv != AndroidRuntime::getJNIEnv()) { 398 ALOGE("Callback: '%s' is not called on the correct thread", __func__); 399 return; 400 } 401 vm->DetachCurrentThread(); 402 } 403} 404 405static void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) { 406 407} 408 409static void le_test_mode_recv_callback(bt_status_t status, 410 uint16_t packet_count) { 411 ALOGV("%s: status:%d packet_count:%d ", __func__, status, packet_count); 412} 413 414static void energy_info_recv_callback(bt_activity_energy_info* p_energy_info, 415 bt_uid_traffic_t* uid_data) { 416 CallbackEnv sCallbackEnv(__func__); 417 if (!sCallbackEnv.valid()) return; 418 419 jsize len = 0; 420 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) { 421 len++; 422 } 423 424 jobjectArray array = sCallbackEnv->NewObjectArray( 425 len, android_bluetooth_UidTraffic.clazz, NULL); 426 jsize i = 0; 427 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) { 428 jobject uidObj = sCallbackEnv->NewObject( 429 android_bluetooth_UidTraffic.clazz, 430 android_bluetooth_UidTraffic.constructor, (jint)data->app_uid, 431 (jlong)data->rx_bytes, (jlong)data->tx_bytes); 432 sCallbackEnv->SetObjectArrayElement(array, i++, uidObj); 433 sCallbackEnv->DeleteLocalRef(uidObj); 434 } 435 436 sCallbackEnv->CallVoidMethod( 437 sJniAdapterServiceObj, method_energyInfo, p_energy_info->status, 438 p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time, 439 p_energy_info->idle_time, p_energy_info->energy_used, array); 440 441 sCallbackEnv->DeleteLocalRef(array); 442} 443 444static bt_callbacks_t sBluetoothCallbacks = { 445 sizeof(sBluetoothCallbacks), adapter_state_change_callback, 446 adapter_properties_callback, remote_device_properties_callback, 447 device_found_callback, discovery_state_changed_callback, 448 pin_request_callback, ssp_request_callback, 449 bond_state_changed_callback, acl_state_changed_callback, 450 callback_thread_event, dut_mode_recv_callback, 451 le_test_mode_recv_callback, energy_info_recv_callback}; 452 453// The callback to call when the wake alarm fires. 454static alarm_cb sAlarmCallback; 455 456// The data to pass to the wake alarm callback. 457static void* sAlarmCallbackData; 458 459static JavaVMAttachArgs sAttachArgs = { 460 .version = JNI_VERSION_1_6, .name = "bluetooth wake", .group = NULL}; 461 462static bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake, 463 alarm_cb cb, void* data) { 464 JNIEnv* env; 465 JavaVM* vm = AndroidRuntime::getJavaVM(); 466 jint status = vm->GetEnv((void**)&env, JNI_VERSION_1_6); 467 468 if (status != JNI_OK && status != JNI_EDETACHED) { 469 ALOGE("%s unable to get environment for JNI call", __func__); 470 return false; 471 } 472 473 if (status == JNI_EDETACHED && 474 vm->AttachCurrentThread(&env, &sAttachArgs) != 0) { 475 ALOGE("%s unable to attach thread to VM", __func__); 476 return false; 477 } 478 479 sAlarmCallback = cb; 480 sAlarmCallbackData = data; 481 482 jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE; 483 jboolean ret = 484 env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm, 485 (jlong)delay_millis, jshould_wake); 486 if (!ret) { 487 sAlarmCallback = NULL; 488 sAlarmCallbackData = NULL; 489 } 490 491 if (status == JNI_EDETACHED) { 492 vm->DetachCurrentThread(); 493 } 494 495 return !!ret; 496} 497 498static int acquire_wake_lock_callout(const char* lock_name) { 499 JNIEnv* env; 500 JavaVM* vm = AndroidRuntime::getJavaVM(); 501 jint status = vm->GetEnv((void**)&env, JNI_VERSION_1_6); 502 if (status != JNI_OK && status != JNI_EDETACHED) { 503 ALOGE("%s unable to get environment for JNI call", __func__); 504 return BT_STATUS_JNI_ENVIRONMENT_ERROR; 505 } 506 if (status == JNI_EDETACHED && 507 vm->AttachCurrentThread(&env, &sAttachArgs) != 0) { 508 ALOGE("%s unable to attach thread to VM", __func__); 509 return BT_STATUS_JNI_THREAD_ATTACH_ERROR; 510 } 511 512 jint ret = BT_STATUS_SUCCESS; 513 jstring lock_name_jni = env->NewStringUTF(lock_name); 514 if (lock_name_jni) { 515 bool acquired = env->CallBooleanMethod( 516 sJniAdapterServiceObj, method_acquireWakeLock, lock_name_jni); 517 if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR; 518 env->DeleteLocalRef(lock_name_jni); 519 } else { 520 ALOGE("%s unable to allocate string: %s", __func__, lock_name); 521 ret = BT_STATUS_NOMEM; 522 } 523 524 if (status == JNI_EDETACHED) { 525 vm->DetachCurrentThread(); 526 } 527 528 return ret; 529} 530 531static int release_wake_lock_callout(const char* lock_name) { 532 JNIEnv* env; 533 JavaVM* vm = AndroidRuntime::getJavaVM(); 534 jint status = vm->GetEnv((void**)&env, JNI_VERSION_1_6); 535 if (status != JNI_OK && status != JNI_EDETACHED) { 536 ALOGE("%s unable to get environment for JNI call", __func__); 537 return BT_STATUS_JNI_ENVIRONMENT_ERROR; 538 } 539 if (status == JNI_EDETACHED && 540 vm->AttachCurrentThread(&env, &sAttachArgs) != 0) { 541 ALOGE("%s unable to attach thread to VM", __func__); 542 return BT_STATUS_JNI_THREAD_ATTACH_ERROR; 543 } 544 545 jint ret = BT_STATUS_SUCCESS; 546 jstring lock_name_jni = env->NewStringUTF(lock_name); 547 if (lock_name_jni) { 548 bool released = env->CallBooleanMethod( 549 sJniAdapterServiceObj, method_releaseWakeLock, lock_name_jni); 550 if (!released) ret = BT_STATUS_WAKELOCK_ERROR; 551 env->DeleteLocalRef(lock_name_jni); 552 } else { 553 ALOGE("%s unable to allocate string: %s", __func__, lock_name); 554 ret = BT_STATUS_NOMEM; 555 } 556 557 if (status == JNI_EDETACHED) { 558 vm->DetachCurrentThread(); 559 } 560 561 return ret; 562} 563 564// Called by Java code when alarm is fired. A wake lock is held by the caller 565// over the duration of this callback. 566static void alarmFiredNative(JNIEnv* env, jobject obj) { 567 if (sAlarmCallback) { 568 sAlarmCallback(sAlarmCallbackData); 569 } else { 570 ALOGE("%s() - Alarm fired with callback not set!", __func__); 571 } 572} 573 574static bt_os_callouts_t sBluetoothOsCallouts = { 575 sizeof(sBluetoothOsCallouts), set_wake_alarm_callout, 576 acquire_wake_lock_callout, release_wake_lock_callout, 577}; 578 579static void classInitNative(JNIEnv* env, jclass clazz) { 580 jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic"); 581 android_bluetooth_UidTraffic.constructor = 582 env->GetMethodID(jniUidTrafficClass, "<init>", "(IJJ)V"); 583 584 jclass jniCallbackClass = 585 env->FindClass("com/android/bluetooth/btservice/JniCallbacks"); 586 sJniCallbacksField = env->GetFieldID( 587 clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;"); 588 589 method_stateChangeCallback = 590 env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V"); 591 592 method_adapterPropertyChangedCallback = env->GetMethodID( 593 jniCallbackClass, "adapterPropertyChangedCallback", "([I[[B)V"); 594 method_discoveryStateChangeCallback = env->GetMethodID( 595 jniCallbackClass, "discoveryStateChangeCallback", "(I)V"); 596 597 method_devicePropertyChangedCallback = env->GetMethodID( 598 jniCallbackClass, "devicePropertyChangedCallback", "([B[I[[B)V"); 599 method_deviceFoundCallback = 600 env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V"); 601 method_pinRequestCallback = 602 env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V"); 603 method_sspRequestCallback = 604 env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V"); 605 606 method_bondStateChangeCallback = 607 env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V"); 608 609 method_aclStateChangeCallback = 610 env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BI)V"); 611 612 method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z"); 613 method_acquireWakeLock = 614 env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z"); 615 method_releaseWakeLock = 616 env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z"); 617 method_energyInfo = env->GetMethodID( 618 clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V"); 619 620 char value[PROPERTY_VALUE_MAX]; 621 property_get("bluetooth.mock_stack", value, ""); 622 623 const char* id = 624 (strcmp(value, "1") ? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID); 625 626 hw_module_t* module; 627 int err = hw_get_module(id, (hw_module_t const**)&module); 628 629 if (err == 0) { 630 hw_device_t* abstraction; 631 err = module->methods->open(module, id, &abstraction); 632 if (err == 0) { 633 bluetooth_module_t* btStack = (bluetooth_module_t*)abstraction; 634 sBluetoothInterface = btStack->get_bluetooth_interface(); 635 } else { 636 ALOGE("Error while opening Bluetooth library"); 637 } 638 } else { 639 ALOGE("No Bluetooth Library found"); 640 } 641} 642 643static bool initNative(JNIEnv* env, jobject obj) { 644 ALOGV("%s", __func__); 645 646 android_bluetooth_UidTraffic.clazz = 647 (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic")); 648 649 sJniAdapterServiceObj = env->NewGlobalRef(obj); 650 sJniCallbacksObj = 651 env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField)); 652 653 if (!sBluetoothInterface) { 654 return JNI_FALSE; 655 } 656 657 int ret = sBluetoothInterface->init(&sBluetoothCallbacks); 658 if (ret != BT_STATUS_SUCCESS) { 659 ALOGE("Error while setting the callbacks: %d\n", ret); 660 sBluetoothInterface = NULL; 661 return JNI_FALSE; 662 } 663 ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts); 664 if (ret != BT_STATUS_SUCCESS) { 665 ALOGE("Error while setting Bluetooth callouts: %d\n", ret); 666 sBluetoothInterface->cleanup(); 667 sBluetoothInterface = NULL; 668 return JNI_FALSE; 669 } 670 671 sBluetoothSocketInterface = 672 (btsock_interface_t*)sBluetoothInterface->get_profile_interface( 673 BT_PROFILE_SOCKETS_ID); 674 if (sBluetoothSocketInterface == NULL) { 675 ALOGE("Error getting socket interface"); 676 } 677 678 return JNI_TRUE; 679} 680 681static bool cleanupNative(JNIEnv* env, jobject obj) { 682 ALOGV("%s", __func__); 683 684 if (!sBluetoothInterface) return JNI_FALSE; 685 686 sBluetoothInterface->cleanup(); 687 ALOGI("%s: return from cleanup", __func__); 688 689 env->DeleteGlobalRef(sJniCallbacksObj); 690 env->DeleteGlobalRef(sJniAdapterServiceObj); 691 env->DeleteGlobalRef(android_bluetooth_UidTraffic.clazz); 692 android_bluetooth_UidTraffic.clazz = NULL; 693 return JNI_TRUE; 694} 695 696static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) { 697 ALOGV("%s", __func__); 698 699 if (!sBluetoothInterface) return JNI_FALSE; 700 int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0); 701 return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE 702 : JNI_FALSE; 703} 704 705static jboolean disableNative(JNIEnv* env, jobject obj) { 706 ALOGV("%s", __func__); 707 708 if (!sBluetoothInterface) return JNI_FALSE; 709 710 int ret = sBluetoothInterface->disable(); 711 /* Retrun JNI_FALSE only when BTIF explicitly reports 712 BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY 713 case which indicates that stack had not been enabled. 714 */ 715 return (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE; 716} 717 718static jboolean startDiscoveryNative(JNIEnv* env, jobject obj) { 719 ALOGV("%s", __func__); 720 721 if (!sBluetoothInterface) return JNI_FALSE; 722 723 int ret = sBluetoothInterface->start_discovery(); 724 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 725} 726 727static jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) { 728 ALOGV("%s", __func__); 729 730 if (!sBluetoothInterface) return JNI_FALSE; 731 732 int ret = sBluetoothInterface->cancel_discovery(); 733 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 734} 735 736static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, 737 jint transport) { 738 ALOGV("%s", __func__); 739 740 if (!sBluetoothInterface) return JNI_FALSE; 741 742 jbyte* addr = env->GetByteArrayElements(address, NULL); 743 if (addr == NULL) { 744 jniThrowIOException(env, EINVAL); 745 return JNI_FALSE; 746 } 747 748 int ret = sBluetoothInterface->create_bond((bt_bdaddr_t*)addr, transport); 749 env->ReleaseByteArrayElements(address, addr, 0); 750 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 751} 752 753static jbyteArray callByteArrayGetter(JNIEnv* env, jobject object, 754 const char* className, 755 const char* methodName) { 756 jclass myClass = env->FindClass(className); 757 jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B"); 758 return (jbyteArray)env->CallObjectMethod(object, myMethod); 759} 760 761static jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj, 762 jbyteArray address, jint transport, 763 jobject oobData) { 764 bt_out_of_band_data_t oob_data; 765 766 memset(&oob_data, 0, sizeof(oob_data)); 767 768 if (!sBluetoothInterface) return JNI_FALSE; 769 770 jbyte* addr = env->GetByteArrayElements(address, NULL); 771 if (addr == NULL) { 772 jniThrowIOException(env, EINVAL); 773 return JNI_FALSE; 774 } 775 776 jbyte* leBtDeviceAddressBytes = NULL; 777 jbyte* smTKBytes = NULL; 778 jbyte* leScCBytes = NULL; 779 jbyte* leScRBytes = NULL; 780 jbyteArray leBtDeviceAddress = NULL; 781 jbyteArray smTK = NULL; 782 jbyteArray leScC = NULL; 783 jbyteArray leScR = NULL; 784 int status = BT_STATUS_FAIL; 785 786 leBtDeviceAddress = callByteArrayGetter( 787 env, oobData, "android/bluetooth/OobData", "getLeBluetoothDeviceAddress"); 788 if (leBtDeviceAddress != NULL) { 789 leBtDeviceAddressBytes = env->GetByteArrayElements(leBtDeviceAddress, NULL); 790 int len = env->GetArrayLength(leBtDeviceAddress); 791 if (len != OOB_LE_BD_ADDR_SIZE) { 792 ALOGI( 793 "%s: wrong length of leBtDeviceAddress, should be empty or %d bytes.", 794 __func__, OOB_LE_BD_ADDR_SIZE); 795 jniThrowIOException(env, EINVAL); 796 goto done; 797 } 798 memcpy(oob_data.le_bt_dev_addr, leBtDeviceAddressBytes, len); 799 } 800 801 smTK = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", 802 "getSecurityManagerTk"); 803 if (smTK != NULL) { 804 smTKBytes = env->GetByteArrayElements(smTK, NULL); 805 int len = env->GetArrayLength(smTK); 806 if (len != OOB_TK_SIZE) { 807 ALOGI("%s: wrong length of smTK, should be empty or %d bytes.", __func__, 808 OOB_TK_SIZE); 809 jniThrowIOException(env, EINVAL); 810 goto done; 811 } 812 memcpy(oob_data.sm_tk, smTKBytes, len); 813 } 814 815 leScC = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", 816 "getLeSecureConnectionsConfirmation"); 817 if (leScC != NULL) { 818 leScCBytes = env->GetByteArrayElements(leScC, NULL); 819 int len = env->GetArrayLength(leScC); 820 if (len != OOB_LE_SC_C_SIZE) { 821 ALOGI( 822 "%s: wrong length of LE SC Confirmation, should be empty or %d " 823 "bytes.", 824 __func__, OOB_LE_SC_C_SIZE); 825 jniThrowIOException(env, EINVAL); 826 goto done; 827 } 828 memcpy(oob_data.le_sc_c, leScCBytes, len); 829 } 830 831 leScR = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", 832 "getLeSecureConnectionsRandom"); 833 if (leScR != NULL) { 834 leScRBytes = env->GetByteArrayElements(leScR, NULL); 835 int len = env->GetArrayLength(leScR); 836 if (len != OOB_LE_SC_R_SIZE) { 837 ALOGI("%s: wrong length of LE SC Random, should be empty or %d bytes.", 838 __func__, OOB_LE_SC_R_SIZE); 839 jniThrowIOException(env, EINVAL); 840 goto done; 841 } 842 memcpy(oob_data.le_sc_r, leScRBytes, len); 843 } 844 845 status = sBluetoothInterface->create_bond_out_of_band((bt_bdaddr_t*)addr, 846 transport, &oob_data); 847 848done: 849 env->ReleaseByteArrayElements(address, addr, 0); 850 851 if (leBtDeviceAddress != NULL) 852 env->ReleaseByteArrayElements(leBtDeviceAddress, leBtDeviceAddressBytes, 0); 853 854 if (smTK != NULL) env->ReleaseByteArrayElements(smTK, smTKBytes, 0); 855 856 if (leScC != NULL) env->ReleaseByteArrayElements(leScC, leScCBytes, 0); 857 858 if (leScR != NULL) env->ReleaseByteArrayElements(leScR, leScRBytes, 0); 859 860 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 861} 862 863static jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 864 ALOGV("%s", __func__); 865 866 if (!sBluetoothInterface) return JNI_FALSE; 867 868 jbyte* addr = env->GetByteArrayElements(address, NULL); 869 if (addr == NULL) { 870 jniThrowIOException(env, EINVAL); 871 return JNI_FALSE; 872 } 873 874 int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t*)addr); 875 env->ReleaseByteArrayElements(address, addr, 0); 876 877 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 878} 879 880static jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 881 ALOGV("%s", __func__); 882 883 if (!sBluetoothInterface) return JNI_FALSE; 884 885 jbyte* addr = env->GetByteArrayElements(address, NULL); 886 if (addr == NULL) { 887 jniThrowIOException(env, EINVAL); 888 return JNI_FALSE; 889 } 890 891 int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t*)addr); 892 env->ReleaseByteArrayElements(address, addr, 0); 893 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 894} 895 896static int getConnectionStateNative(JNIEnv* env, jobject obj, 897 jbyteArray address) { 898 ALOGV("%s", __func__); 899 if (!sBluetoothInterface) return JNI_FALSE; 900 901 jbyte* addr = env->GetByteArrayElements(address, NULL); 902 if (addr == NULL) { 903 jniThrowIOException(env, EINVAL); 904 return JNI_FALSE; 905 } 906 907 int ret = sBluetoothInterface->get_connection_state((bt_bdaddr_t*)addr); 908 env->ReleaseByteArrayElements(address, addr, 0); 909 910 return ret; 911} 912 913static jboolean pinReplyNative(JNIEnv* env, jobject obj, jbyteArray address, 914 jboolean accept, jint len, jbyteArray pinArray) { 915 ALOGV("%s", __func__); 916 917 if (!sBluetoothInterface) return JNI_FALSE; 918 919 jbyte* addr = env->GetByteArrayElements(address, NULL); 920 if (addr == NULL) { 921 jniThrowIOException(env, EINVAL); 922 return JNI_FALSE; 923 } 924 925 jbyte* pinPtr = NULL; 926 if (accept) { 927 pinPtr = env->GetByteArrayElements(pinArray, NULL); 928 if (pinPtr == NULL) { 929 jniThrowIOException(env, EINVAL); 930 env->ReleaseByteArrayElements(address, addr, 0); 931 return JNI_FALSE; 932 } 933 } 934 935 int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len, 936 (bt_pin_code_t*)pinPtr); 937 env->ReleaseByteArrayElements(address, addr, 0); 938 env->ReleaseByteArrayElements(pinArray, pinPtr, 0); 939 940 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 941} 942 943static jboolean sspReplyNative(JNIEnv* env, jobject obj, jbyteArray address, 944 jint type, jboolean accept, jint passkey) { 945 ALOGV("%s", __func__); 946 947 if (!sBluetoothInterface) return JNI_FALSE; 948 949 jbyte* addr = env->GetByteArrayElements(address, NULL); 950 if (addr == NULL) { 951 jniThrowIOException(env, EINVAL); 952 return JNI_FALSE; 953 } 954 955 int ret = sBluetoothInterface->ssp_reply( 956 (bt_bdaddr_t*)addr, (bt_ssp_variant_t)type, accept, passkey); 957 env->ReleaseByteArrayElements(address, addr, 0); 958 959 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 960} 961 962static jboolean setAdapterPropertyNative(JNIEnv* env, jobject obj, jint type, 963 jbyteArray value) { 964 ALOGV("%s", __func__); 965 966 if (!sBluetoothInterface) return JNI_FALSE; 967 968 jbyte* val = env->GetByteArrayElements(value, NULL); 969 bt_property_t prop; 970 prop.type = (bt_property_type_t)type; 971 prop.len = env->GetArrayLength(value); 972 prop.val = val; 973 974 int ret = sBluetoothInterface->set_adapter_property(&prop); 975 env->ReleaseByteArrayElements(value, val, 0); 976 977 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 978} 979 980static jboolean getAdapterPropertiesNative(JNIEnv* env, jobject obj) { 981 ALOGV("%s", __func__); 982 983 if (!sBluetoothInterface) return JNI_FALSE; 984 985 int ret = sBluetoothInterface->get_adapter_properties(); 986 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 987} 988 989static jboolean getAdapterPropertyNative(JNIEnv* env, jobject obj, jint type) { 990 ALOGV("%s", __func__); 991 992 if (!sBluetoothInterface) return JNI_FALSE; 993 994 int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t)type); 995 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 996} 997 998static jboolean getDevicePropertyNative(JNIEnv* env, jobject obj, 999 jbyteArray address, jint type) { 1000 ALOGV("%s", __func__); 1001 1002 if (!sBluetoothInterface) return JNI_FALSE; 1003 1004 jbyte* addr = env->GetByteArrayElements(address, NULL); 1005 if (addr == NULL) { 1006 jniThrowIOException(env, EINVAL); 1007 return JNI_FALSE; 1008 } 1009 1010 int ret = sBluetoothInterface->get_remote_device_property( 1011 (bt_bdaddr_t*)addr, (bt_property_type_t)type); 1012 env->ReleaseByteArrayElements(address, addr, 0); 1013 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1014} 1015 1016static jboolean setDevicePropertyNative(JNIEnv* env, jobject obj, 1017 jbyteArray address, jint type, 1018 jbyteArray value) { 1019 ALOGV("%s", __func__); 1020 1021 if (!sBluetoothInterface) return JNI_FALSE; 1022 1023 jbyte* val = env->GetByteArrayElements(value, NULL); 1024 if (val == NULL) { 1025 jniThrowIOException(env, EINVAL); 1026 return JNI_FALSE; 1027 } 1028 1029 jbyte* addr = env->GetByteArrayElements(address, NULL); 1030 if (addr == NULL) { 1031 env->ReleaseByteArrayElements(value, val, 0); 1032 jniThrowIOException(env, EINVAL); 1033 return JNI_FALSE; 1034 } 1035 1036 bt_property_t prop; 1037 prop.type = (bt_property_type_t)type; 1038 prop.len = env->GetArrayLength(value); 1039 prop.val = val; 1040 1041 int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t*)addr, 1042 &prop); 1043 env->ReleaseByteArrayElements(value, val, 0); 1044 env->ReleaseByteArrayElements(address, addr, 0); 1045 1046 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1047} 1048 1049static jboolean getRemoteServicesNative(JNIEnv* env, jobject obj, 1050 jbyteArray address) { 1051 ALOGV("%s", __func__); 1052 1053 if (!sBluetoothInterface) return JNI_FALSE; 1054 1055 jbyte* addr = addr = env->GetByteArrayElements(address, NULL); 1056 if (addr == NULL) { 1057 jniThrowIOException(env, EINVAL); 1058 return JNI_FALSE; 1059 } 1060 1061 int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t*)addr); 1062 env->ReleaseByteArrayElements(address, addr, 0); 1063 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1064} 1065 1066static int connectSocketNative(JNIEnv* env, jobject object, jbyteArray address, 1067 jint type, jbyteArray uuidObj, jint channel, 1068 jint flag, jint callingUid) { 1069 if (!sBluetoothSocketInterface) return -1; 1070 1071 jbyte* addr = env->GetByteArrayElements(address, NULL); 1072 if (!addr) { 1073 ALOGE("failed to get Bluetooth device address"); 1074 return -1; 1075 } 1076 1077 jbyte* uuid = NULL; 1078 if (uuidObj != NULL) { 1079 uuid = env->GetByteArrayElements(uuidObj, NULL); 1080 if (!uuid) { 1081 ALOGE("failed to get uuid"); 1082 env->ReleaseByteArrayElements(address, addr, 0); 1083 return -1; 1084 } 1085 } 1086 1087 int socket_fd = -1; 1088 bt_status_t status = sBluetoothSocketInterface->connect( 1089 (bt_bdaddr_t*)addr, (btsock_type_t)type, (const uint8_t*)uuid, channel, 1090 &socket_fd, flag, callingUid); 1091 if (status != BT_STATUS_SUCCESS) { 1092 ALOGE("Socket connection failed: %d", status); 1093 socket_fd = -1; 1094 } else if (socket_fd < 0) { 1095 ALOGE("Fail to create file descriptor on socket fd"); 1096 } 1097 1098 env->ReleaseByteArrayElements(address, addr, 0); 1099 env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1100 return socket_fd; 1101} 1102 1103static int createSocketChannelNative(JNIEnv* env, jobject object, jint type, 1104 jstring name_str, jbyteArray uuidObj, 1105 jint channel, jint flag, jint callingUid) { 1106 if (!sBluetoothSocketInterface) return -1; 1107 1108 ALOGV("%s: SOCK FLAG = %x", __func__, flag); 1109 1110 const char* service_name = NULL; 1111 if (name_str != NULL) { 1112 service_name = env->GetStringUTFChars(name_str, NULL); 1113 } 1114 1115 jbyte* uuid = NULL; 1116 if (uuidObj != NULL) { 1117 uuid = env->GetByteArrayElements(uuidObj, NULL); 1118 if (!uuid) { 1119 ALOGE("failed to get uuid"); 1120 if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 1121 return -1; 1122 } 1123 } 1124 1125 int socket_fd = -1; 1126 bt_status_t status = sBluetoothSocketInterface->listen( 1127 (btsock_type_t)type, service_name, (const uint8_t*)uuid, channel, 1128 &socket_fd, flag, callingUid); 1129 if (status != BT_STATUS_SUCCESS) { 1130 ALOGE("Socket listen failed: %d", status); 1131 socket_fd = -1; 1132 } else if (socket_fd < 0) { 1133 ALOGE("Fail to creat file descriptor on socket fd"); 1134 } 1135 1136 if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 1137 if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1138 return socket_fd; 1139} 1140 1141static jboolean configHciSnoopLogNative(JNIEnv* env, jobject obj, 1142 jboolean enable) { 1143 ALOGV("%s", __func__); 1144 1145 if (!sBluetoothInterface) return JNI_FALSE; 1146 1147 int ret = sBluetoothInterface->config_hci_snoop_log(enable); 1148 1149 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1150} 1151 1152static int readEnergyInfo() { 1153 ALOGV("%s", __func__); 1154 1155 if (!sBluetoothInterface) return JNI_FALSE; 1156 int ret = sBluetoothInterface->read_energy_info(); 1157 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1158} 1159 1160static void dumpNative(JNIEnv* env, jobject obj, jobject fdObj, 1161 jobjectArray argArray) { 1162 ALOGV("%s", __func__); 1163 if (!sBluetoothInterface) return; 1164 1165 int fd = jniGetFDFromFileDescriptor(env, fdObj); 1166 if (fd < 0) return; 1167 1168 int numArgs = env->GetArrayLength(argArray); 1169 1170 jstring* argObjs = new jstring[numArgs]; 1171 const char** args = nullptr; 1172 if (numArgs > 0) args = new const char*[numArgs]; 1173 1174 for (int i = 0; i < numArgs; i++) { 1175 argObjs[i] = (jstring)env->GetObjectArrayElement(argArray, i); 1176 args[i] = env->GetStringUTFChars(argObjs[i], NULL); 1177 } 1178 1179 sBluetoothInterface->dump(fd, args); 1180 1181 for (int i = 0; i < numArgs; i++) { 1182 env->ReleaseStringUTFChars(argObjs[i], args[i]); 1183 } 1184 1185 delete[] args; 1186 delete[] argObjs; 1187} 1188 1189static jboolean factoryResetNative(JNIEnv* env, jobject obj) { 1190 ALOGV("%s", __func__); 1191 if (!sBluetoothInterface) return JNI_FALSE; 1192 int ret = sBluetoothInterface->config_clear(); 1193 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1194} 1195 1196static void interopDatabaseClearNative(JNIEnv* env, jobject obj) { 1197 ALOGV("%s", __func__); 1198 if (!sBluetoothInterface) return; 1199 sBluetoothInterface->interop_database_clear(); 1200} 1201 1202static void interopDatabaseAddNative(JNIEnv* env, jobject obj, int feature, 1203 jbyteArray address, int length) { 1204 ALOGV("%s", __func__); 1205 if (!sBluetoothInterface) return; 1206 1207 jbyte* addr = env->GetByteArrayElements(address, NULL); 1208 if (addr == NULL) { 1209 jniThrowIOException(env, EINVAL); 1210 return; 1211 } 1212 1213 sBluetoothInterface->interop_database_add(feature, (bt_bdaddr_t*)addr, 1214 length); 1215 env->ReleaseByteArrayElements(address, addr, 0); 1216} 1217 1218static JNINativeMethod sMethods[] = { 1219 /* name, signature, funcPtr */ 1220 {"classInitNative", "()V", (void*)classInitNative}, 1221 {"initNative", "()Z", (void*)initNative}, 1222 {"cleanupNative", "()V", (void*)cleanupNative}, 1223 {"enableNative", "(Z)Z", (void*)enableNative}, 1224 {"disableNative", "()Z", (void*)disableNative}, 1225 {"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative}, 1226 {"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative}, 1227 {"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative}, 1228 {"getDevicePropertyNative", "([BI)Z", (void*)getDevicePropertyNative}, 1229 {"setDevicePropertyNative", "([BI[B)Z", (void*)setDevicePropertyNative}, 1230 {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative}, 1231 {"cancelDiscoveryNative", "()Z", (void*)cancelDiscoveryNative}, 1232 {"createBondNative", "([BI)Z", (void*)createBondNative}, 1233 {"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z", 1234 (void*)createBondOutOfBandNative}, 1235 {"removeBondNative", "([B)Z", (void*)removeBondNative}, 1236 {"cancelBondNative", "([B)Z", (void*)cancelBondNative}, 1237 {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative}, 1238 {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative}, 1239 {"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative}, 1240 {"getRemoteServicesNative", "([B)Z", (void*)getRemoteServicesNative}, 1241 {"connectSocketNative", "([BI[BIII)I", (void*)connectSocketNative}, 1242 {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I", 1243 (void*)createSocketChannelNative}, 1244 {"configHciSnoopLogNative", "(Z)Z", (void*)configHciSnoopLogNative}, 1245 {"alarmFiredNative", "()V", (void*)alarmFiredNative}, 1246 {"readEnergyInfo", "()I", (void*)readEnergyInfo}, 1247 {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V", 1248 (void*)dumpNative}, 1249 {"factoryResetNative", "()Z", (void*)factoryResetNative}, 1250 {"interopDatabaseClearNative", "()V", (void*)interopDatabaseClearNative}, 1251 {"interopDatabaseAddNative", "(I[BI)V", (void*)interopDatabaseAddNative}}; 1252 1253int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) { 1254 return jniRegisterNativeMethods( 1255 env, "com/android/bluetooth/btservice/AdapterService", sMethods, 1256 NELEM(sMethods)); 1257} 1258 1259} /* namespace android */ 1260 1261/* 1262 * JNI Initialization 1263 */ 1264jint JNI_OnLoad(JavaVM* jvm, void* reserved) { 1265 JNIEnv* e; 1266 int status; 1267 1268 ALOGV("Bluetooth Adapter Service : loading JNI\n"); 1269 1270 // Check JNI version 1271 if (jvm->GetEnv((void**)&e, JNI_VERSION_1_6)) { 1272 ALOGE("JNI version mismatch error"); 1273 return JNI_ERR; 1274 } 1275 1276 status = android::register_com_android_bluetooth_btservice_AdapterService(e); 1277 if (status < 0) { 1278 ALOGE("jni adapter service registration failure, status: %d", status); 1279 return JNI_ERR; 1280 } 1281 1282 status = android::register_com_android_bluetooth_hfp(e); 1283 if (status < 0) { 1284 ALOGE("jni hfp registration failure, status: %d", status); 1285 return JNI_ERR; 1286 } 1287 1288 status = android::register_com_android_bluetooth_hfpclient(e); 1289 if (status < 0) { 1290 ALOGE("jni hfp client registration failure, status: %d", status); 1291 return JNI_ERR; 1292 } 1293 1294 status = android::register_com_android_bluetooth_a2dp(e); 1295 if (status < 0) { 1296 ALOGE("jni a2dp source registration failure: %d", status); 1297 return JNI_ERR; 1298 } 1299 1300 status = android::register_com_android_bluetooth_a2dp_sink(e); 1301 if (status < 0) { 1302 ALOGE("jni a2dp sink registration failure: %d", status); 1303 return JNI_ERR; 1304 } 1305 1306 status = android::register_com_android_bluetooth_avrcp(e); 1307 if (status < 0) { 1308 ALOGE("jni avrcp target registration failure: %d", status); 1309 return JNI_ERR; 1310 } 1311 1312 status = android::register_com_android_bluetooth_avrcp_controller(e); 1313 if (status < 0) { 1314 ALOGE("jni avrcp controller registration failure: %d", status); 1315 return JNI_ERR; 1316 } 1317 1318 status = android::register_com_android_bluetooth_hid(e); 1319 if (status < 0) { 1320 ALOGE("jni hid registration failure: %d", status); 1321 return JNI_ERR; 1322 } 1323 1324 status = android::register_com_android_bluetooth_hidd(e); 1325 if (status < 0) { 1326 ALOGE("jni hidd registration failure: %d", status); 1327 return JNI_ERR; 1328 } 1329 1330 status = android::register_com_android_bluetooth_hdp(e); 1331 if (status < 0) { 1332 ALOGE("jni hdp registration failure: %d", status); 1333 return JNI_ERR; 1334 } 1335 1336 status = android::register_com_android_bluetooth_pan(e); 1337 if (status < 0) { 1338 ALOGE("jni pan registration failure: %d", status); 1339 return JNI_ERR; 1340 } 1341 1342 status = android::register_com_android_bluetooth_gatt(e); 1343 if (status < 0) { 1344 ALOGE("jni gatt registration failure: %d", status); 1345 return JNI_ERR; 1346 } 1347 1348 status = android::register_com_android_bluetooth_sdp(e); 1349 if (status < 0) { 1350 ALOGE("jni sdp registration failure: %d", status); 1351 return JNI_ERR; 1352 } 1353 1354 return JNI_VERSION_1_6; 1355} 1356