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