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