com_android_bluetooth_btservice_AdapterService.cpp revision c63ef51ba5f9d355239959bcfe8803987adb1f38
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 if (!checkCallbackThread()) { 293 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 294 return; 295 } 296 if (!bd_addr) { 297 ALOGE("Address is null in %s", __FUNCTION__); 298 return; 299 } 300 addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 301 if (addr == NULL) { 302 ALOGE("Address allocation failed in %s", __FUNCTION__); 303 return; 304 } 305 callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr); 306 307 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status, 308 addr, (jint)state); 309 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 310 callbackEnv->DeleteLocalRef(addr); 311} 312 313static void acl_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr, 314 bt_acl_state_t state) 315{ 316 jbyteArray addr; 317 if (!checkCallbackThread()) { 318 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 319 return; 320 } 321 if (!bd_addr) { 322 ALOGE("Address is null in %s", __FUNCTION__); 323 return; 324 } 325 addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 326 if (addr == NULL) { 327 ALOGE("Address allocation failed in %s", __FUNCTION__); 328 return; 329 } 330 callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr); 331 332 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, (jint) status, 333 addr, (jint)state); 334 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 335 callbackEnv->DeleteLocalRef(addr); 336} 337 338static void discovery_state_changed_callback(bt_discovery_state_t state) { 339 if (!checkCallbackThread()) { 340 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 341 return; 342 } 343 344 ALOGV("%s: DiscoveryState:%d ", __FUNCTION__, state); 345 346 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_discoveryStateChangeCallback, 347 (jint)state); 348 349 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 350} 351 352static void pin_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod, 353 bool min_16_digits) { 354 jbyteArray addr = NULL; 355 jbyteArray devname = NULL; 356 if (!checkCallbackThread()) { 357 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 358 return; 359 } 360 if (!bd_addr) { 361 ALOGE("Address is null in %s", __FUNCTION__); 362 return; 363 } 364 365 addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 366 if (addr == NULL) goto Fail; 367 callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr); 368 369 devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t)); 370 if (devname == NULL) goto Fail; 371 372 callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname); 373 374 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, addr, devname, cod, 375 min_16_digits); 376 377 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 378 callbackEnv->DeleteLocalRef(addr); 379 callbackEnv->DeleteLocalRef(devname); 380 return; 381 382Fail: 383 if (addr) callbackEnv->DeleteLocalRef(addr); 384 if (devname) callbackEnv->DeleteLocalRef(devname); 385 ALOGE("Error while allocating in: %s", __FUNCTION__); 386} 387 388static void ssp_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod, 389 bt_ssp_variant_t pairing_variant, uint32_t pass_key) { 390 jbyteArray addr = NULL; 391 jbyteArray devname = NULL; 392 if (!checkCallbackThread()) { 393 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 394 return; 395 } 396 if (!bd_addr) { 397 ALOGE("Address is null in %s", __FUNCTION__); 398 return; 399 } 400 401 addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 402 if (addr == NULL) goto Fail; 403 callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr); 404 405 devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t)); 406 if (devname == NULL) goto Fail; 407 callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname); 408 409 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, addr, devname, cod, 410 (jint) pairing_variant, pass_key); 411 412 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 413 callbackEnv->DeleteLocalRef(addr); 414 callbackEnv->DeleteLocalRef(devname); 415 return; 416 417Fail: 418 if (addr) callbackEnv->DeleteLocalRef(addr); 419 if (devname) callbackEnv->DeleteLocalRef(devname); 420 421 ALOGE("Error while allocating in: %s", __FUNCTION__); 422} 423 424static void callback_thread_event(bt_cb_thread_evt event) { 425 JavaVM* vm = AndroidRuntime::getJavaVM(); 426 if (event == ASSOCIATE_JVM) { 427 JavaVMAttachArgs args; 428 char name[] = "BT Service Callback Thread"; 429 args.version = JNI_VERSION_1_6; 430 args.name = name; 431 args.group = NULL; 432 vm->AttachCurrentThread(&callbackEnv, &args); 433 ALOGV("Callback thread attached: %p", callbackEnv); 434 } else if (event == DISASSOCIATE_JVM) { 435 if (!checkCallbackThread()) { 436 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 437 return; 438 } 439 vm->DetachCurrentThread(); 440 } 441} 442 443static void dut_mode_recv_callback (uint16_t opcode, uint8_t *buf, uint8_t len) { 444 445} 446static void le_test_mode_recv_callback (bt_status_t status, uint16_t packet_count) { 447 448 ALOGV("%s: status:%d packet_count:%d ", __FUNCTION__, status, packet_count); 449} 450 451static void energy_info_recv_callback(bt_activity_energy_info *p_energy_info, 452 bt_uid_traffic_t* /* uid_data */) 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 = "bluetooth wake", 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_JNI_ENVIRONMENT_ERROR; 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_JNI_THREAD_ATTACH_ERROR; 540 } 541 542 jint ret = BT_STATUS_SUCCESS; 543 jstring lock_name_jni = env->NewStringUTF(lock_name); 544 if (lock_name_jni) { 545 bool acquired = env->CallBooleanMethod(sJniAdapterServiceObj, 546 method_acquireWakeLock, lock_name_jni); 547 if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR; 548 env->DeleteLocalRef(lock_name_jni); 549 } else { 550 ALOGE("%s unable to allocate string: %s", __func__, lock_name); 551 ret = BT_STATUS_NOMEM; 552 } 553 554 if (status == JNI_EDETACHED) { 555 vm->DetachCurrentThread(); 556 } 557 558 return ret; 559} 560 561static int release_wake_lock_callout(const char *lock_name) { 562 JNIEnv *env; 563 JavaVM *vm = AndroidRuntime::getJavaVM(); 564 jint status = vm->GetEnv((void **)&env, JNI_VERSION_1_6); 565 if (status != JNI_OK && status != JNI_EDETACHED) { 566 ALOGE("%s unable to get environment for JNI call", __func__); 567 return BT_STATUS_JNI_ENVIRONMENT_ERROR; 568 } 569 if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, &sAttachArgs) != 0) { 570 ALOGE("%s unable to attach thread to VM", __func__); 571 return BT_STATUS_JNI_THREAD_ATTACH_ERROR; 572 } 573 574 jint ret = BT_STATUS_SUCCESS; 575 jstring lock_name_jni = env->NewStringUTF(lock_name); 576 if (lock_name_jni) { 577 bool released = env->CallBooleanMethod(sJniAdapterServiceObj, 578 method_releaseWakeLock, lock_name_jni); 579 if (!released) ret = BT_STATUS_WAKELOCK_ERROR; 580 env->DeleteLocalRef(lock_name_jni); 581 } else { 582 ALOGE("%s unable to allocate string: %s", __func__, lock_name); 583 ret = BT_STATUS_NOMEM; 584 } 585 586 if (status == JNI_EDETACHED) { 587 vm->DetachCurrentThread(); 588 } 589 590 return ret; 591} 592 593// Called by Java code when alarm is fired. A wake lock is held by the caller 594// over the duration of this callback. 595static void alarmFiredNative(JNIEnv *env, jobject obj) { 596 if (sAlarmCallback) { 597 sAlarmCallback(sAlarmCallbackData); 598 } else { 599 ALOGE("%s() - Alarm fired with callback not set!", __FUNCTION__); 600 } 601} 602 603static bt_os_callouts_t sBluetoothOsCallouts = { 604 sizeof(sBluetoothOsCallouts), 605 set_wake_alarm_callout, 606 acquire_wake_lock_callout, 607 release_wake_lock_callout, 608}; 609 610 611 612static void classInitNative(JNIEnv* env, jclass clazz) { 613 int err; 614 hw_module_t* module; 615 616 jclass jniCallbackClass = 617 env->FindClass("com/android/bluetooth/btservice/JniCallbacks"); 618 sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks", 619 "Lcom/android/bluetooth/btservice/JniCallbacks;"); 620 621 method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V"); 622 623 method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass, 624 "adapterPropertyChangedCallback", 625 "([I[[B)V"); 626 method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass, 627 "discoveryStateChangeCallback", "(I)V"); 628 629 method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass, 630 "devicePropertyChangedCallback", 631 "([B[I[[B)V"); 632 method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V"); 633 method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback", 634 "([B[BIZ)V"); 635 method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback", 636 "([B[BIII)V"); 637 638 method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass, 639 "bondStateChangeCallback", "(I[BI)V"); 640 641 method_aclStateChangeCallback = env->GetMethodID(jniCallbackClass, 642 "aclStateChangeCallback", "(I[BI)V"); 643 644 method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z"); 645 method_acquireWakeLock = env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z"); 646 method_releaseWakeLock = env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z"); 647 method_energyInfo = env->GetMethodID(clazz, "energyInfoCallback", "(IIJJJJ)V"); 648 649 char value[PROPERTY_VALUE_MAX]; 650 property_get("bluetooth.mock_stack", value, ""); 651 652 const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID); 653 654 err = hw_get_module(id, (hw_module_t const**)&module); 655 656 if (err == 0) { 657 hw_device_t* abstraction; 658 err = module->methods->open(module, id, &abstraction); 659 if (err == 0) { 660 bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction; 661 sBluetoothInterface = btStack->get_bluetooth_interface(); 662 } else { 663 ALOGE("Error while opening Bluetooth library"); 664 } 665 } else { 666 ALOGE("No Bluetooth Library found"); 667 } 668} 669 670static bool initNative(JNIEnv* env, jobject obj) { 671 ALOGV("%s:",__FUNCTION__); 672 673 sJniAdapterServiceObj = env->NewGlobalRef(obj); 674 sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField)); 675 676 if (sBluetoothInterface) { 677 int ret = sBluetoothInterface->init(&sBluetoothCallbacks); 678 if (ret != BT_STATUS_SUCCESS) { 679 ALOGE("Error while setting the callbacks: %d\n", ret); 680 sBluetoothInterface = NULL; 681 return JNI_FALSE; 682 } 683 ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts); 684 if (ret != BT_STATUS_SUCCESS) { 685 ALOGE("Error while setting Bluetooth callouts: %d\n", ret); 686 sBluetoothInterface->cleanup(); 687 sBluetoothInterface = NULL; 688 return JNI_FALSE; 689 } 690 691 if ( (sBluetoothSocketInterface = (btsock_interface_t *) 692 sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) { 693 ALOGE("Error getting socket interface"); 694 } 695 696 return JNI_TRUE; 697 } 698 return JNI_FALSE; 699} 700 701static bool cleanupNative(JNIEnv *env, jobject obj) { 702 ALOGV("%s:",__FUNCTION__); 703 704 jboolean result = JNI_FALSE; 705 if (!sBluetoothInterface) return result; 706 707 sBluetoothInterface->cleanup(); 708 ALOGI("%s: return from cleanup",__FUNCTION__); 709 710 env->DeleteGlobalRef(sJniCallbacksObj); 711 env->DeleteGlobalRef(sJniAdapterServiceObj); 712 return JNI_TRUE; 713} 714 715static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) { 716 ALOGV("%s:",__FUNCTION__); 717 718 jboolean result = JNI_FALSE; 719 if (!sBluetoothInterface) return result; 720 int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0); 721 result = (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE; 722 return result; 723} 724 725static jboolean disableNative(JNIEnv* env, jobject obj) { 726 ALOGV("%s:",__FUNCTION__); 727 728 jboolean result = JNI_FALSE; 729 if (!sBluetoothInterface) return result; 730 731 int ret = sBluetoothInterface->disable(); 732 /* Retrun JNI_FALSE only when BTIF explicitly reports 733 BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY 734 case which indicates that stack had not been enabled. 735 */ 736 result = (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE; 737 return result; 738} 739 740static jboolean startDiscoveryNative(JNIEnv* env, jobject obj) { 741 ALOGV("%s:",__FUNCTION__); 742 743 jboolean result = JNI_FALSE; 744 if (!sBluetoothInterface) return result; 745 746 int ret = sBluetoothInterface->start_discovery(); 747 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 748 return result; 749} 750 751static jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) { 752 ALOGV("%s:",__FUNCTION__); 753 754 jboolean result = JNI_FALSE; 755 if (!sBluetoothInterface) return result; 756 757 int ret = sBluetoothInterface->cancel_discovery(); 758 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 759 return result; 760} 761 762static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, jint transport) { 763 ALOGV("%s:",__FUNCTION__); 764 765 jbyte *addr; 766 jboolean result = JNI_FALSE; 767 768 if (!sBluetoothInterface) return result; 769 770 addr = env->GetByteArrayElements(address, NULL); 771 if (addr == NULL) { 772 jniThrowIOException(env, EINVAL); 773 return result; 774 } 775 776 int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr, transport); 777 env->ReleaseByteArrayElements(address, addr, 0); 778 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 779 780 return result; 781} 782 783static jbyteArray callByteArrayGetter(JNIEnv* env, jobject object, 784 const char* className, 785 const char* methodName) { 786 jclass myClass = env->FindClass(className); 787 jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B"); 788 return (jbyteArray) env->CallObjectMethod(object, myMethod); 789} 790 791static jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj, jbyteArray address, 792 jint transport, jobject oobData) { 793 jbyte *addr; 794 jboolean result = JNI_FALSE; 795 bt_out_of_band_data_t oob_data; 796 797 memset(&oob_data, 0, sizeof(oob_data)); 798 799 if (!sBluetoothInterface) return result; 800 801 addr = env->GetByteArrayElements(address, NULL); 802 if (addr == NULL) { 803 jniThrowIOException(env, EINVAL); 804 return result; 805 } 806 807 jbyte* smTKBytes = NULL; 808 jbyteArray smTK = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", "getSecurityManagerTk"); 809 if (smTK != NULL) { 810 smTKBytes = env->GetByteArrayElements(smTK, NULL); 811 int len = env->GetArrayLength(smTK); 812 if (len != OOB_TK_SIZE) { 813 ALOGI("%s: wrong length of smTK, should be empty or %d bytes.", __FUNCTION__, OOB_TK_SIZE); 814 jniThrowIOException(env, EINVAL); 815 goto done; 816 } 817 memcpy(oob_data.sm_tk, smTKBytes, len); 818 } 819 820 if (sBluetoothInterface->create_bond_out_of_band((bt_bdaddr_t *)addr, transport, &oob_data) 821 == BT_STATUS_SUCCESS) 822 result = JNI_TRUE; 823 824done: 825 env->ReleaseByteArrayElements(address, addr, 0); 826 827 if (smTK != NULL) 828 env->ReleaseByteArrayElements(smTK, smTKBytes, 0); 829 830 return result; 831} 832 833static jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 834 ALOGV("%s:",__FUNCTION__); 835 836 jbyte *addr; 837 jboolean result; 838 if (!sBluetoothInterface) return JNI_FALSE; 839 840 addr = env->GetByteArrayElements(address, NULL); 841 if (addr == NULL) { 842 jniThrowIOException(env, EINVAL); 843 return JNI_FALSE; 844 } 845 846 int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t *)addr); 847 env->ReleaseByteArrayElements(address, addr, 0); 848 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 849 850 return result; 851} 852 853static jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 854 ALOGV("%s:",__FUNCTION__); 855 856 jbyte *addr; 857 jboolean result; 858 if (!sBluetoothInterface) return JNI_FALSE; 859 860 addr = env->GetByteArrayElements(address, NULL); 861 if (addr == NULL) { 862 jniThrowIOException(env, EINVAL); 863 return JNI_FALSE; 864 } 865 866 int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t *)addr); 867 env->ReleaseByteArrayElements(address, addr, 0); 868 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 869 870 return result; 871} 872 873static int getConnectionStateNative(JNIEnv* env, jobject obj, jbyteArray address) { 874 ALOGV("%s:",__FUNCTION__); 875 if (!sBluetoothInterface) return JNI_FALSE; 876 877 jbyte *addr = env->GetByteArrayElements(address, NULL); 878 if (addr == NULL) { 879 jniThrowIOException(env, EINVAL); 880 return JNI_FALSE; 881 } 882 883 int ret = sBluetoothInterface->get_connection_state((bt_bdaddr_t *)addr); 884 env->ReleaseByteArrayElements(address, addr, 0); 885 886 return ret; 887} 888 889static jboolean pinReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept, 890 jint len, jbyteArray pinArray) { 891 ALOGV("%s:",__FUNCTION__); 892 893 jbyte *addr, *pinPtr = NULL; 894 jboolean result = JNI_FALSE; 895 if (!sBluetoothInterface) return result; 896 897 addr = env->GetByteArrayElements(address, NULL); 898 if (addr == NULL) { 899 jniThrowIOException(env, EINVAL); 900 return result; 901 } 902 903 if (accept) { 904 pinPtr = env->GetByteArrayElements(pinArray, NULL); 905 if (pinPtr == NULL) { 906 jniThrowIOException(env, EINVAL); 907 env->ReleaseByteArrayElements(address, addr, 0); 908 return result; 909 } 910 } 911 912 int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len, 913 (bt_pin_code_t *) pinPtr); 914 env->ReleaseByteArrayElements(address, addr, 0); 915 env->ReleaseByteArrayElements(pinArray, pinPtr, 0); 916 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 917 918 return result; 919} 920 921static jboolean sspReplyNative(JNIEnv *env, jobject obj, jbyteArray address, 922 jint type, jboolean accept, jint passkey) { 923 ALOGV("%s:",__FUNCTION__); 924 925 jbyte *addr; 926 jboolean result = JNI_FALSE; 927 if (!sBluetoothInterface) return result; 928 929 addr = env->GetByteArrayElements(address, NULL); 930 if (addr == NULL) { 931 jniThrowIOException(env, EINVAL); 932 return result; 933 } 934 935 int ret = sBluetoothInterface->ssp_reply((bt_bdaddr_t *)addr, 936 (bt_ssp_variant_t) type, accept, passkey); 937 env->ReleaseByteArrayElements(address, addr, 0); 938 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 939 940 return result; 941} 942 943static jboolean setAdapterPropertyNative(JNIEnv *env, jobject obj, jint type, jbyteArray value) { 944 ALOGV("%s:",__FUNCTION__); 945 946 jbyte *val; 947 jboolean result = JNI_FALSE; 948 if (!sBluetoothInterface) return result; 949 950 val = env->GetByteArrayElements(value, NULL); 951 bt_property_t prop; 952 prop.type = (bt_property_type_t) type; 953 prop.len = env->GetArrayLength(value); 954 prop.val = val; 955 956 int ret = sBluetoothInterface->set_adapter_property(&prop); 957 env->ReleaseByteArrayElements(value, val, 0); 958 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 959 960 return result; 961} 962 963static jboolean getAdapterPropertiesNative(JNIEnv *env, jobject obj) { 964 ALOGV("%s:",__FUNCTION__); 965 966 jboolean result = JNI_FALSE; 967 if (!sBluetoothInterface) return result; 968 969 int ret = sBluetoothInterface->get_adapter_properties(); 970 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 971 972 return result; 973} 974 975static jboolean getAdapterPropertyNative(JNIEnv *env, jobject obj, jint type) { 976 ALOGV("%s:",__FUNCTION__); 977 978 jboolean result = JNI_FALSE; 979 if (!sBluetoothInterface) return result; 980 981 int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t) type); 982 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 983 984 return result; 985} 986 987static jboolean getDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, jint type) { 988 ALOGV("%s:",__FUNCTION__); 989 990 jbyte *addr = NULL; 991 jboolean result = JNI_FALSE; 992 if (!sBluetoothInterface) return result; 993 994 addr = env->GetByteArrayElements(address, NULL); 995 if (addr == NULL) { 996 jniThrowIOException(env, EINVAL); 997 return result; 998 } 999 1000 int ret = sBluetoothInterface->get_remote_device_property((bt_bdaddr_t *)addr, 1001 (bt_property_type_t) type); 1002 env->ReleaseByteArrayElements(address, addr, 0); 1003 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1004 1005 return result; 1006} 1007 1008static jboolean setDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, 1009 jint type, jbyteArray value) { 1010 ALOGV("%s:",__FUNCTION__); 1011 1012 jbyte *val, *addr; 1013 jboolean result = JNI_FALSE; 1014 if (!sBluetoothInterface) return result; 1015 1016 val = env->GetByteArrayElements(value, NULL); 1017 if (val == NULL) { 1018 jniThrowIOException(env, EINVAL); 1019 return result; 1020 } 1021 1022 addr = env->GetByteArrayElements(address, NULL); 1023 if (addr == NULL) { 1024 env->ReleaseByteArrayElements(value, val, 0); 1025 jniThrowIOException(env, EINVAL); 1026 return result; 1027 } 1028 1029 1030 bt_property_t prop; 1031 prop.type = (bt_property_type_t) type; 1032 prop.len = env->GetArrayLength(value); 1033 prop.val = val; 1034 1035 int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t *)addr, &prop); 1036 env->ReleaseByteArrayElements(value, val, 0); 1037 env->ReleaseByteArrayElements(address, addr, 0); 1038 1039 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1040 1041 return result; 1042} 1043 1044static jboolean getRemoteServicesNative(JNIEnv *env, jobject obj, jbyteArray address) { 1045 ALOGV("%s:",__FUNCTION__); 1046 1047 jbyte *addr = NULL; 1048 jboolean result = JNI_FALSE; 1049 if (!sBluetoothInterface) return result; 1050 1051 addr = env->GetByteArrayElements(address, NULL); 1052 if (addr == NULL) { 1053 jniThrowIOException(env, EINVAL); 1054 return result; 1055 } 1056 1057 int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t *)addr); 1058 env->ReleaseByteArrayElements(address, addr, 0); 1059 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1060 return result; 1061} 1062 1063static int connectSocketNative(JNIEnv *env, jobject object, jbyteArray address, jint type, 1064 jbyteArray uuidObj, jint channel, jint flag, jint callingUid) { 1065 jbyte *addr = NULL, *uuid = NULL; 1066 int socket_fd; 1067 bt_status_t status; 1068 1069 if (!sBluetoothSocketInterface) return -1; 1070 1071 addr = env->GetByteArrayElements(address, NULL); 1072 if (!addr) { 1073 ALOGE("failed to get Bluetooth device address"); 1074 goto Fail; 1075 } 1076 1077 if(uuidObj != NULL) { 1078 uuid = env->GetByteArrayElements(uuidObj, NULL); 1079 if (!uuid) { 1080 ALOGE("failed to get uuid"); 1081 goto Fail; 1082 } 1083 } 1084 1085 if ( (status = sBluetoothSocketInterface->connect((bt_bdaddr_t *) addr, (btsock_type_t) type, 1086 (const uint8_t*) uuid, channel, &socket_fd, flag, callingUid)) 1087 != BT_STATUS_SUCCESS) { 1088 ALOGE("Socket connection failed: %d", status); 1089 goto Fail; 1090 } 1091 1092 1093 if (socket_fd < 0) { 1094 ALOGE("Fail to create file descriptor on socket fd"); 1095 goto Fail; 1096 } 1097 env->ReleaseByteArrayElements(address, addr, 0); 1098 env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1099 return socket_fd; 1100 1101Fail: 1102 if (addr) env->ReleaseByteArrayElements(address, addr, 0); 1103 if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1104 1105 return -1; 1106} 1107 1108static int createSocketChannelNative(JNIEnv *env, jobject object, jint type, 1109 jstring name_str, jbyteArray uuidObj, 1110 jint channel, jint flag, jint callingUid) { 1111 const char *service_name = NULL; 1112 jbyte *uuid = NULL; 1113 int socket_fd; 1114 bt_status_t status; 1115 1116 if (!sBluetoothSocketInterface) return -1; 1117 1118 ALOGV("%s: SOCK FLAG = %x", __FUNCTION__, flag); 1119 1120 if(name_str != NULL) { 1121 service_name = env->GetStringUTFChars(name_str, NULL); 1122 } 1123 1124 if(uuidObj != NULL) { 1125 uuid = env->GetByteArrayElements(uuidObj, NULL); 1126 if (!uuid) { 1127 ALOGE("failed to get uuid"); 1128 goto Fail; 1129 } 1130 } 1131 if ( (status = sBluetoothSocketInterface->listen((btsock_type_t) type, service_name, 1132 (const uint8_t*) uuid, channel, &socket_fd, flag, callingUid)) 1133 != BT_STATUS_SUCCESS) { 1134 ALOGE("Socket listen failed: %d", status); 1135 goto Fail; 1136 } 1137 1138 if (socket_fd < 0) { 1139 ALOGE("Fail to creat file descriptor on socket fd"); 1140 goto Fail; 1141 } 1142 if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 1143 if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1144 return socket_fd; 1145 1146Fail: 1147 if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 1148 if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1149 return -1; 1150} 1151 1152static jboolean configHciSnoopLogNative(JNIEnv* env, jobject obj, jboolean enable) { 1153 ALOGV("%s:",__FUNCTION__); 1154 1155 jboolean result = JNI_FALSE; 1156 1157 if (!sBluetoothInterface) return result; 1158 1159 int ret = sBluetoothInterface->config_hci_snoop_log(enable); 1160 1161 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1162 1163 return result; 1164} 1165 1166static int readEnergyInfo() 1167{ 1168 ALOGV("%s:",__FUNCTION__); 1169 jboolean result = JNI_FALSE; 1170 if (!sBluetoothInterface) return result; 1171 int ret = sBluetoothInterface->read_energy_info(); 1172 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1173 return result; 1174} 1175 1176static void dumpNative(JNIEnv *env, jobject obj, jobject fdObj, 1177 jobjectArray argArray) 1178{ 1179 ALOGV("%s()", __FUNCTION__); 1180 if (!sBluetoothInterface) return; 1181 1182 int fd = jniGetFDFromFileDescriptor(env, fdObj); 1183 if (fd < 0) return; 1184 1185 int numArgs = env->GetArrayLength(argArray); 1186 1187 jstring *argObjs = new jstring[numArgs]; 1188 const char **args = nullptr; 1189 if (numArgs > 0) 1190 args = new const char*[numArgs]; 1191 1192 for (int i = 0; i < numArgs; i++) { 1193 argObjs[i] = (jstring) env->GetObjectArrayElement(argArray, i); 1194 args[i] = env->GetStringUTFChars(argObjs[i], NULL); 1195 } 1196 1197 sBluetoothInterface->dump(fd, args); 1198 1199 for (int i = 0; i < numArgs; i++) { 1200 env->ReleaseStringUTFChars(argObjs[i], args[i]); 1201 } 1202 1203 delete[] args; 1204 delete[] argObjs; 1205} 1206 1207static jboolean factoryResetNative(JNIEnv *env, jobject obj) { 1208 ALOGV("%s:", __FUNCTION__); 1209 if (!sBluetoothInterface) return JNI_FALSE; 1210 int ret = sBluetoothInterface->config_clear(); 1211 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1212} 1213 1214static JNINativeMethod sMethods[] = { 1215 /* name, signature, funcPtr */ 1216 {"classInitNative", "()V", (void *) classInitNative}, 1217 {"initNative", "()Z", (void *) initNative}, 1218 {"cleanupNative", "()V", (void*) cleanupNative}, 1219 {"enableNative", "(Z)Z", (void*) enableNative}, 1220 {"disableNative", "()Z", (void*) disableNative}, 1221 {"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative}, 1222 {"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative}, 1223 {"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative}, 1224 {"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative}, 1225 {"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative}, 1226 {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative}, 1227 {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative}, 1228 {"createBondNative", "([BI)Z", (void*) createBondNative}, 1229 {"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z", (void*) createBondOutOfBandNative}, 1230 {"removeBondNative", "([B)Z", (void*) removeBondNative}, 1231 {"cancelBondNative", "([B)Z", (void*) cancelBondNative}, 1232 {"getConnectionStateNative", "([B)I", (void*) getConnectionStateNative}, 1233 {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative}, 1234 {"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative}, 1235 {"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative}, 1236 {"connectSocketNative", "([BI[BIII)I", (void*) connectSocketNative}, 1237 {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I", 1238 (void*) createSocketChannelNative}, 1239 {"configHciSnoopLogNative", "(Z)Z", (void*) configHciSnoopLogNative}, 1240 {"alarmFiredNative", "()V", (void *) alarmFiredNative}, 1241 {"readEnergyInfo", "()I", (void*) readEnergyInfo}, 1242 {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V", (void*) dumpNative}, 1243 {"factoryResetNative", "()Z", (void*)factoryResetNative} 1244}; 1245 1246int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) 1247{ 1248 return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService", 1249 sMethods, NELEM(sMethods)); 1250} 1251 1252} /* namespace android */ 1253 1254 1255/* 1256 * JNI Initialization 1257 */ 1258jint JNI_OnLoad(JavaVM *jvm, void *reserved) 1259{ 1260 JNIEnv *e; 1261 int status; 1262 1263 ALOGV("Bluetooth Adapter Service : loading JNI\n"); 1264 1265 // Check JNI version 1266 if (jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) { 1267 ALOGE("JNI version mismatch error"); 1268 return JNI_ERR; 1269 } 1270 1271 if ((status = android::register_com_android_bluetooth_btservice_AdapterService(e)) < 0) { 1272 ALOGE("jni adapter service registration failure, status: %d", status); 1273 return JNI_ERR; 1274 } 1275 1276 if ((status = android::register_com_android_bluetooth_hfp(e)) < 0) { 1277 ALOGE("jni hfp registration failure, status: %d", status); 1278 return JNI_ERR; 1279 } 1280 1281 if ((status = android::register_com_android_bluetooth_hfpclient(e)) < 0) { 1282 ALOGE("jni hfp client registration failure, status: %d", status); 1283 return JNI_ERR; 1284 } 1285 1286 if ((status = android::register_com_android_bluetooth_a2dp(e)) < 0) { 1287 ALOGE("jni a2dp source registration failure: %d", status); 1288 return JNI_ERR; 1289 } 1290 1291 if ((status = android::register_com_android_bluetooth_a2dp_sink(e)) < 0) { 1292 ALOGE("jni a2dp sink registration failure: %d", status); 1293 return JNI_ERR; 1294 } 1295 1296 if ((status = android::register_com_android_bluetooth_avrcp(e)) < 0) { 1297 ALOGE("jni avrcp target registration failure: %d", status); 1298 return JNI_ERR; 1299 } 1300 1301 if ((status = android::register_com_android_bluetooth_avrcp_controller(e)) < 0) { 1302 ALOGE("jni avrcp controller registration failure: %d", status); 1303 return JNI_ERR; 1304 } 1305 1306 if ((status = android::register_com_android_bluetooth_hid(e)) < 0) { 1307 ALOGE("jni hid registration failure: %d", status); 1308 return JNI_ERR; 1309 } 1310 1311 if ((status = android::register_com_android_bluetooth_hdp(e)) < 0) { 1312 ALOGE("jni hdp registration failure: %d", status); 1313 return JNI_ERR; 1314 } 1315 1316 if ((status = android::register_com_android_bluetooth_pan(e)) < 0) { 1317 ALOGE("jni pan registration failure: %d", status); 1318 return JNI_ERR; 1319 } 1320 1321 if ((status = android::register_com_android_bluetooth_gatt(e)) < 0) { 1322 ALOGE("jni gatt registration failure: %d", status); 1323 return JNI_ERR; 1324 } 1325 1326 if ((status = android::register_com_android_bluetooth_sdp(e)) < 0) { 1327 ALOGE("jni sdp registration failure: %d", status); 1328 return JNI_ERR; 1329 } 1330 1331 return JNI_VERSION_1_6; 1332} 1333