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