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 "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 
     33 namespace android {
     34 
     35 #define ADDITIONAL_NREFS 50
     36 static jmethodID method_stateChangeCallback;
     37 static jmethodID method_adapterPropertyChangedCallback;
     38 static jmethodID method_devicePropertyChangedCallback;
     39 static jmethodID method_deviceFoundCallback;
     40 static jmethodID method_pinRequestCallback;
     41 static jmethodID method_sspRequestCallback;
     42 static jmethodID method_bondStateChangeCallback;
     43 static jmethodID method_aclStateChangeCallback;
     44 static jmethodID method_discoveryStateChangeCallback;
     45 static jmethodID method_setWakeAlarm;
     46 static jmethodID method_acquireWakeLock;
     47 static jmethodID method_releaseWakeLock;
     48 static jmethodID method_deviceMasInstancesFoundCallback;
     49 static jmethodID method_energyInfo;
     50 
     51 static const bt_interface_t *sBluetoothInterface = NULL;
     52 static const btsock_interface_t *sBluetoothSocketInterface = NULL;
     53 static const btmce_interface_t *sBluetoothMceInterface = NULL;
     54 static JNIEnv *callbackEnv = NULL;
     55 
     56 static jobject sJniAdapterServiceObj;
     57 static jobject sJniCallbacksObj;
     58 static jfieldID sJniCallbacksField;
     59 
     60 
     61 const bt_interface_t* getBluetoothInterface() {
     62     return sBluetoothInterface;
     63 }
     64 
     65 JNIEnv* getCallbackEnv() {
     66     return callbackEnv;
     67 }
     68 
     69 void 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 
     78 static 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 
     87 static 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 
     99 static 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;
    114 Fail:
    115     if (propVal) callbackEnv->DeleteLocalRef(propVal);
    116     ALOGE("Error while allocation of array in %s", __FUNCTION__);
    117     return -1;
    118 }
    119 
    120 static 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 
    182 static 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 
    252 Fail:
    253     ALOGE("Error while allocation byte array in %s", __FUNCTION__);
    254 }
    255 
    256 
    257 static 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 
    290 static 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 
    315 static 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 
    341 static 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 
    356 static 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 
    383 Fail:
    384     if (addr) callbackEnv->DeleteLocalRef(addr);
    385     if (devname) callbackEnv->DeleteLocalRef(devname);
    386     ALOGE("Error while allocating in: %s", __FUNCTION__);
    387 }
    388 
    389 static 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 
    417 Fail:
    418     if (addr) callbackEnv->DeleteLocalRef(addr);
    419     if (devname) callbackEnv->DeleteLocalRef(devname);
    420 
    421     ALOGE("Error while allocating in: %s", __FUNCTION__);
    422 }
    423 
    424 static 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 
    443 static void dut_mode_recv_callback (uint16_t opcode, uint8_t *buf, uint8_t len) {
    444 
    445 }
    446 static 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 
    451 static 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 
    465 static 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.
    484 static alarm_cb sAlarmCallback;
    485 
    486 // The data to pass to the wake alarm callback.
    487 static void *sAlarmCallbackData;
    488 
    489 static JavaVMAttachArgs sAttachArgs = {
    490   .version = JNI_VERSION_1_6,
    491   .name = "bluedroid wake/alarm thread",
    492   .group = NULL
    493 };
    494 
    495 static 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     sAlarmCallback = cb;
    511     sAlarmCallbackData = data;
    512 
    513     jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE;
    514     jboolean ret = env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm, (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 
    532     if (status != JNI_OK && status != JNI_EDETACHED) {
    533         ALOGE("%s unable to get environment for JNI call", __func__);
    534         return BT_STATUS_FAIL;
    535     }
    536 
    537     if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, &sAttachArgs) != 0) {
    538         ALOGE("%s unable to attach thread to VM", __func__);
    539         return BT_STATUS_FAIL;
    540     }
    541 
    542     jboolean ret = JNI_FALSE;
    543     jstring lock_name_jni = env->NewStringUTF(lock_name);
    544     if (lock_name_jni) {
    545         ret = env->CallBooleanMethod(sJniAdapterServiceObj, method_acquireWakeLock, lock_name_jni);
    546         env->DeleteLocalRef(lock_name_jni);
    547     } else {
    548         ALOGE("%s unable to allocate string: %s", __func__, lock_name);
    549     }
    550 
    551     if (status == JNI_EDETACHED) {
    552         vm->DetachCurrentThread();
    553     }
    554 
    555     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
    556 }
    557 
    558 static int release_wake_lock_callout(const char *lock_name) {
    559     JNIEnv *env;
    560     JavaVM *vm = AndroidRuntime::getJavaVM();
    561     jint status = vm->GetEnv((void **)&env, JNI_VERSION_1_6);
    562 
    563     if (status != JNI_OK && status != JNI_EDETACHED) {
    564         ALOGE("%s unable to get environment for JNI call", __func__);
    565         return BT_STATUS_FAIL;
    566     }
    567 
    568     if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, &sAttachArgs) != 0) {
    569         ALOGE("%s unable to attach thread to VM", __func__);
    570         return BT_STATUS_FAIL;
    571     }
    572 
    573     jboolean ret = JNI_FALSE;
    574     jstring lock_name_jni = env->NewStringUTF(lock_name);
    575     if (lock_name_jni) {
    576         ret = env->CallBooleanMethod(sJniAdapterServiceObj, method_releaseWakeLock, lock_name_jni);
    577         env->DeleteLocalRef(lock_name_jni);
    578     } else {
    579         ALOGE("%s unable to allocate string: %s", __func__, lock_name);
    580     }
    581 
    582     if (status == JNI_EDETACHED) {
    583         vm->DetachCurrentThread();
    584     }
    585 
    586     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
    587 }
    588 
    589 // Called by Java code when alarm is fired. A wake lock is held by the caller
    590 // over the duration of this callback.
    591 static void alarmFiredNative(JNIEnv *env, jobject obj) {
    592     if (sAlarmCallback) {
    593         sAlarmCallback(sAlarmCallbackData);
    594     } else {
    595         ALOGE("%s() - Alarm fired with callback not set!", __FUNCTION__);
    596     }
    597 }
    598 
    599 static void remote_mas_instances_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
    600                                           int num_instances, btmce_mas_instance_t *instances)
    601 {
    602     if (!checkCallbackThread()) {
    603        ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
    604        return;
    605     }
    606 
    607     ALOGV("%s: Status is: %d, Instances: %d", __FUNCTION__, status, num_instances);
    608 
    609     if (status != BT_STATUS_SUCCESS) {
    610         ALOGE("%s: Status %d is incorrect", __FUNCTION__, status);
    611         return;
    612     }
    613 
    614     callbackEnv->PushLocalFrame(ADDITIONAL_NREFS);
    615 
    616     jbyteArray addr = NULL;
    617     jobjectArray a_name = NULL;
    618     jintArray a_scn = NULL;
    619     jintArray a_masid = NULL;
    620     jintArray a_msgtype = NULL;
    621     jclass mclass;
    622 
    623     mclass = callbackEnv->FindClass("java/lang/String");
    624 
    625     addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    626     if (addr == NULL) goto clean;
    627 
    628     callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
    629 
    630     a_name = callbackEnv->NewObjectArray(num_instances, mclass, NULL);
    631     if (a_name == NULL) goto clean;
    632 
    633     a_scn = callbackEnv->NewIntArray(num_instances);
    634     if (a_scn == NULL) goto clean;
    635 
    636     a_masid = callbackEnv->NewIntArray(num_instances);
    637     if (a_masid == NULL) goto clean;
    638 
    639     a_msgtype = callbackEnv->NewIntArray(num_instances);
    640     if (a_msgtype == NULL) goto clean;
    641 
    642     for (int i = 0; i < num_instances; i++) {
    643         jstring name = callbackEnv->NewStringUTF(instances[i].p_name);
    644 
    645         callbackEnv->SetObjectArrayElement(a_name, i, name);
    646         callbackEnv->SetIntArrayRegion(a_scn, i, 1, &instances[i].scn);
    647         callbackEnv->SetIntArrayRegion(a_masid, i, 1, &instances[i].id);
    648         callbackEnv->SetIntArrayRegion(a_msgtype, i, 1, &instances[i].msg_types);
    649 
    650         callbackEnv->DeleteLocalRef(name);
    651     }
    652 
    653     callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceMasInstancesFoundCallback,
    654             (jint) status, addr, a_name, a_scn, a_masid, a_msgtype);
    655     checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
    656 
    657 clean:
    658     if (addr != NULL) callbackEnv->DeleteLocalRef(addr);
    659     if (a_name != NULL) callbackEnv->DeleteLocalRef(a_name);
    660     if (a_scn != NULL) callbackEnv->DeleteLocalRef(a_scn);
    661     if (a_masid != NULL) callbackEnv->DeleteLocalRef(a_masid);
    662     if (a_msgtype != NULL) callbackEnv->DeleteLocalRef(a_msgtype);
    663     callbackEnv->PopLocalFrame(NULL);
    664 }
    665 
    666 static bt_os_callouts_t sBluetoothOsCallouts = {
    667     sizeof(sBluetoothOsCallouts),
    668     set_wake_alarm_callout,
    669     acquire_wake_lock_callout,
    670     release_wake_lock_callout,
    671 };
    672 
    673 static btmce_callbacks_t sBluetoothMceCallbacks = {
    674     sizeof(sBluetoothMceCallbacks),
    675     remote_mas_instances_callback,
    676 };
    677 
    678 static void classInitNative(JNIEnv* env, jclass clazz) {
    679     int err;
    680     hw_module_t* module;
    681 
    682     jclass jniCallbackClass =
    683         env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
    684     sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks",
    685         "Lcom/android/bluetooth/btservice/JniCallbacks;");
    686 
    687     method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
    688 
    689     method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass,
    690                                                              "adapterPropertyChangedCallback",
    691                                                              "([I[[B)V");
    692     method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass,
    693                                                            "discoveryStateChangeCallback", "(I)V");
    694 
    695     method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass,
    696                                                             "devicePropertyChangedCallback",
    697                                                             "([B[I[[B)V");
    698     method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
    699     method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback",
    700                                                  "([B[BI)V");
    701     method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback",
    702                                                  "([B[BIII)V");
    703 
    704     method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass,
    705                                                      "bondStateChangeCallback", "(I[BI)V");
    706 
    707     method_aclStateChangeCallback = env->GetMethodID(jniCallbackClass,
    708                                                     "aclStateChangeCallback", "(I[BI)V");
    709 
    710     method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
    711     method_acquireWakeLock = env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
    712     method_releaseWakeLock = env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");
    713     method_deviceMasInstancesFoundCallback = env->GetMethodID(jniCallbackClass,
    714                                                     "deviceMasInstancesFoundCallback",
    715                                                     "(I[B[Ljava/lang/String;[I[I[I)V");
    716     method_energyInfo = env->GetMethodID(clazz, "energyInfoCallback", "(IIJJJJ)V");
    717 
    718     char value[PROPERTY_VALUE_MAX];
    719     property_get("bluetooth.mock_stack", value, "");
    720 
    721     const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
    722 
    723     err = hw_get_module(id, (hw_module_t const**)&module);
    724 
    725     if (err == 0) {
    726         hw_device_t* abstraction;
    727         err = module->methods->open(module, id, &abstraction);
    728         if (err == 0) {
    729             bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
    730             sBluetoothInterface = btStack->get_bluetooth_interface();
    731         } else {
    732            ALOGE("Error while opening Bluetooth library");
    733         }
    734     } else {
    735         ALOGE("No Bluetooth Library found");
    736     }
    737 }
    738 
    739 static bool initNative(JNIEnv* env, jobject obj) {
    740     ALOGV("%s:",__FUNCTION__);
    741 
    742     sJniAdapterServiceObj = env->NewGlobalRef(obj);
    743     sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
    744 
    745     if (sBluetoothInterface) {
    746         int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
    747         if (ret != BT_STATUS_SUCCESS) {
    748             ALOGE("Error while setting the callbacks: %d\n", ret);
    749             sBluetoothInterface = NULL;
    750             return JNI_FALSE;
    751         }
    752         ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
    753         if (ret != BT_STATUS_SUCCESS) {
    754             ALOGE("Error while setting Bluetooth callouts: %d\n", ret);
    755             sBluetoothInterface->cleanup();
    756             sBluetoothInterface = NULL;
    757             return JNI_FALSE;
    758         }
    759 
    760         if ( (sBluetoothSocketInterface = (btsock_interface_t *)
    761                   sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
    762                 ALOGE("Error getting socket interface");
    763         }
    764 
    765         if ( (sBluetoothMceInterface = (btmce_interface_t *)
    766                   sBluetoothInterface->get_profile_interface(BT_PROFILE_MAP_CLIENT_ID)) == NULL) {
    767                 ALOGE("Error getting mapclient interface");
    768         } else {
    769             if ( (sBluetoothMceInterface->init(&sBluetoothMceCallbacks)) != BT_STATUS_SUCCESS) {
    770                 ALOGE("Failed to initialize Bluetooth MCE");
    771                 sBluetoothMceInterface = NULL;
    772             }
    773         }
    774 
    775         return JNI_TRUE;
    776     }
    777     return JNI_FALSE;
    778 }
    779 
    780 static bool cleanupNative(JNIEnv *env, jobject obj) {
    781     ALOGV("%s:",__FUNCTION__);
    782 
    783     jboolean result = JNI_FALSE;
    784     if (!sBluetoothInterface) return result;
    785 
    786     sBluetoothInterface->cleanup();
    787     ALOGI("%s: return from cleanup",__FUNCTION__);
    788 
    789     env->DeleteGlobalRef(sJniCallbacksObj);
    790     env->DeleteGlobalRef(sJniAdapterServiceObj);
    791     return JNI_TRUE;
    792 }
    793 
    794 static jboolean enableNative(JNIEnv* env, jobject obj) {
    795     ALOGV("%s:",__FUNCTION__);
    796 
    797     jboolean result = JNI_FALSE;
    798     if (!sBluetoothInterface) return result;
    799 
    800     int ret = sBluetoothInterface->enable();
    801     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    802     return result;
    803 }
    804 
    805 static jboolean disableNative(JNIEnv* env, jobject obj) {
    806     ALOGV("%s:",__FUNCTION__);
    807 
    808     jboolean result = JNI_FALSE;
    809     if (!sBluetoothInterface) return result;
    810 
    811     int ret = sBluetoothInterface->disable();
    812     /* Retrun JNI_FALSE only when BTIF explicitly reports
    813        BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY
    814        case which indicates that stack had not been enabled.
    815     */
    816     result = (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE;
    817     return result;
    818 }
    819 
    820 static jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
    821     ALOGV("%s:",__FUNCTION__);
    822 
    823     jboolean result = JNI_FALSE;
    824     if (!sBluetoothInterface) return result;
    825 
    826     int ret = sBluetoothInterface->start_discovery();
    827     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    828     return result;
    829 }
    830 
    831 static jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) {
    832     ALOGV("%s:",__FUNCTION__);
    833 
    834     jboolean result = JNI_FALSE;
    835     if (!sBluetoothInterface) return result;
    836 
    837     int ret = sBluetoothInterface->cancel_discovery();
    838     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    839     return result;
    840 }
    841 
    842 static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, jint transport) {
    843     ALOGV("%s:",__FUNCTION__);
    844 
    845     jbyte *addr;
    846     jboolean result = JNI_FALSE;
    847 
    848     if (!sBluetoothInterface) return result;
    849 
    850     addr = env->GetByteArrayElements(address, NULL);
    851     if (addr == NULL) {
    852         jniThrowIOException(env, EINVAL);
    853         return result;
    854     }
    855 
    856     int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr, transport);
    857     env->ReleaseByteArrayElements(address, addr, 0);
    858     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    859 
    860     return result;
    861 }
    862 
    863 static jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
    864     ALOGV("%s:",__FUNCTION__);
    865 
    866     jbyte *addr;
    867     jboolean result;
    868     if (!sBluetoothInterface) return JNI_FALSE;
    869 
    870     addr = env->GetByteArrayElements(address, NULL);
    871     if (addr == NULL) {
    872         jniThrowIOException(env, EINVAL);
    873         return JNI_FALSE;
    874     }
    875 
    876     int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t *)addr);
    877     env->ReleaseByteArrayElements(address, addr, 0);
    878     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    879 
    880     return result;
    881 }
    882 
    883 static jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
    884     ALOGV("%s:",__FUNCTION__);
    885 
    886     jbyte *addr;
    887     jboolean result;
    888     if (!sBluetoothInterface) return JNI_FALSE;
    889 
    890     addr = env->GetByteArrayElements(address, NULL);
    891     if (addr == NULL) {
    892         jniThrowIOException(env, EINVAL);
    893         return JNI_FALSE;
    894     }
    895 
    896     int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t *)addr);
    897     env->ReleaseByteArrayElements(address, addr, 0);
    898     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    899 
    900     return result;
    901 }
    902 
    903 static int getConnectionStateNative(JNIEnv* env, jobject obj, jbyteArray address) {
    904     ALOGV("%s:",__FUNCTION__);
    905     if (!sBluetoothInterface) return JNI_FALSE;
    906 
    907     jbyte *addr = env->GetByteArrayElements(address, NULL);
    908     if (addr == NULL) {
    909         jniThrowIOException(env, EINVAL);
    910         return JNI_FALSE;
    911     }
    912 
    913     int ret = sBluetoothInterface->get_connection_state((bt_bdaddr_t *)addr);
    914     env->ReleaseByteArrayElements(address, addr, 0);
    915 
    916     return ret;
    917 }
    918 
    919 static jboolean pinReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept,
    920                                jint len, jbyteArray pinArray) {
    921     ALOGV("%s:",__FUNCTION__);
    922 
    923     jbyte *addr, *pinPtr = NULL;
    924     jboolean result = JNI_FALSE;
    925     if (!sBluetoothInterface) return result;
    926 
    927     addr = env->GetByteArrayElements(address, NULL);
    928     if (addr == NULL) {
    929         jniThrowIOException(env, EINVAL);
    930         return result;
    931     }
    932 
    933     if (accept) {
    934         pinPtr = env->GetByteArrayElements(pinArray, NULL);
    935         if (pinPtr == NULL) {
    936            jniThrowIOException(env, EINVAL);
    937            env->ReleaseByteArrayElements(address, addr, 0);
    938            return result;
    939         }
    940     }
    941 
    942     int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len,
    943                                               (bt_pin_code_t *) pinPtr);
    944     env->ReleaseByteArrayElements(address, addr, 0);
    945     env->ReleaseByteArrayElements(pinArray, pinPtr, 0);
    946     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    947 
    948     return result;
    949 }
    950 
    951 static jboolean sspReplyNative(JNIEnv *env, jobject obj, jbyteArray address,
    952                                jint type, jboolean accept, jint passkey) {
    953     ALOGV("%s:",__FUNCTION__);
    954 
    955     jbyte *addr;
    956     jboolean result = JNI_FALSE;
    957     if (!sBluetoothInterface) return result;
    958 
    959     addr = env->GetByteArrayElements(address, NULL);
    960     if (addr == NULL) {
    961         jniThrowIOException(env, EINVAL);
    962         return result;
    963     }
    964 
    965     int ret = sBluetoothInterface->ssp_reply((bt_bdaddr_t *)addr,
    966          (bt_ssp_variant_t) type, accept, passkey);
    967     env->ReleaseByteArrayElements(address, addr, 0);
    968     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    969 
    970     return result;
    971 }
    972 
    973 static jboolean setAdapterPropertyNative(JNIEnv *env, jobject obj, jint type, jbyteArray value) {
    974     ALOGV("%s:",__FUNCTION__);
    975 
    976     jbyte *val;
    977     jboolean result = JNI_FALSE;
    978     if (!sBluetoothInterface) return result;
    979 
    980     val = env->GetByteArrayElements(value, NULL);
    981     bt_property_t prop;
    982     prop.type = (bt_property_type_t) type;
    983     prop.len = env->GetArrayLength(value);
    984     prop.val = val;
    985 
    986     int ret = sBluetoothInterface->set_adapter_property(&prop);
    987     env->ReleaseByteArrayElements(value, val, 0);
    988     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    989 
    990     return result;
    991 }
    992 
    993 static jboolean getAdapterPropertiesNative(JNIEnv *env, jobject obj) {
    994     ALOGV("%s:",__FUNCTION__);
    995 
    996     jboolean result = JNI_FALSE;
    997     if (!sBluetoothInterface) return result;
    998 
    999     int ret = sBluetoothInterface->get_adapter_properties();
   1000     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
   1001 
   1002     return result;
   1003 }
   1004 
   1005 static jboolean getAdapterPropertyNative(JNIEnv *env, jobject obj, jint type) {
   1006     ALOGV("%s:",__FUNCTION__);
   1007 
   1008     jboolean result = JNI_FALSE;
   1009     if (!sBluetoothInterface) return result;
   1010 
   1011     int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t) type);
   1012     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
   1013 
   1014     return result;
   1015 }
   1016 
   1017 static jboolean getDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, jint type) {
   1018     ALOGV("%s:",__FUNCTION__);
   1019 
   1020     jbyte *addr = NULL;
   1021     jboolean result = JNI_FALSE;
   1022     if (!sBluetoothInterface) return result;
   1023 
   1024     addr = env->GetByteArrayElements(address, NULL);
   1025     if (addr == NULL) {
   1026         jniThrowIOException(env, EINVAL);
   1027         return result;
   1028     }
   1029 
   1030     int ret = sBluetoothInterface->get_remote_device_property((bt_bdaddr_t *)addr,
   1031                                                               (bt_property_type_t) type);
   1032     env->ReleaseByteArrayElements(address, addr, 0);
   1033     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
   1034 
   1035     return result;
   1036 }
   1037 
   1038 static jboolean setDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address,
   1039                                         jint type, jbyteArray value) {
   1040     ALOGV("%s:",__FUNCTION__);
   1041 
   1042     jbyte *val, *addr;
   1043     jboolean result = JNI_FALSE;
   1044     if (!sBluetoothInterface) return result;
   1045 
   1046     val = env->GetByteArrayElements(value, NULL);
   1047     if (val == NULL) {
   1048         jniThrowIOException(env, EINVAL);
   1049         return result;
   1050     }
   1051 
   1052     addr = env->GetByteArrayElements(address, NULL);
   1053     if (addr == NULL) {
   1054         env->ReleaseByteArrayElements(value, val, 0);
   1055         jniThrowIOException(env, EINVAL);
   1056         return result;
   1057     }
   1058 
   1059 
   1060     bt_property_t prop;
   1061     prop.type = (bt_property_type_t) type;
   1062     prop.len = env->GetArrayLength(value);
   1063     prop.val = val;
   1064 
   1065     int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t *)addr, &prop);
   1066     env->ReleaseByteArrayElements(value, val, 0);
   1067     env->ReleaseByteArrayElements(address, addr, 0);
   1068 
   1069     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
   1070 
   1071     return result;
   1072 }
   1073 
   1074 static jboolean getRemoteServicesNative(JNIEnv *env, jobject obj, jbyteArray address) {
   1075     ALOGV("%s:",__FUNCTION__);
   1076 
   1077     jbyte *addr = NULL;
   1078     jboolean result = JNI_FALSE;
   1079     if (!sBluetoothInterface) return result;
   1080 
   1081     addr = env->GetByteArrayElements(address, NULL);
   1082     if (addr == NULL) {
   1083         jniThrowIOException(env, EINVAL);
   1084         return result;
   1085     }
   1086 
   1087     int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t *)addr);
   1088     env->ReleaseByteArrayElements(address, addr, 0);
   1089     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
   1090     return result;
   1091 }
   1092 
   1093 static jboolean getRemoteMasInstancesNative(JNIEnv *env, jobject obj, jbyteArray address) {
   1094     ALOGV("%s:",__FUNCTION__);
   1095 
   1096     jbyte *addr = NULL;
   1097     jboolean result = JNI_FALSE;
   1098     if (!sBluetoothMceInterface) return result;
   1099 
   1100     addr = env->GetByteArrayElements(address, NULL);
   1101     if (addr == NULL) {
   1102         jniThrowIOException(env, EINVAL);
   1103         return result;
   1104     }
   1105 
   1106     int ret = sBluetoothMceInterface->get_remote_mas_instances((bt_bdaddr_t *)addr);
   1107     env->ReleaseByteArrayElements(address, addr, NULL);
   1108     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
   1109     return result;
   1110 }
   1111 
   1112 static int connectSocketNative(JNIEnv *env, jobject object, jbyteArray address, jint type,
   1113                                    jbyteArray uuidObj, jint channel, jint flag) {
   1114     jbyte *addr = NULL, *uuid = NULL;
   1115     int socket_fd;
   1116     bt_status_t status;
   1117 
   1118     if (!sBluetoothSocketInterface) return -1;
   1119 
   1120     addr = env->GetByteArrayElements(address, NULL);
   1121     if (!addr) {
   1122         ALOGE("failed to get Bluetooth device address");
   1123         goto Fail;
   1124     }
   1125 
   1126     uuid = env->GetByteArrayElements(uuidObj, NULL);
   1127     if (!uuid) {
   1128         ALOGE("failed to get uuid");
   1129         goto Fail;
   1130     }
   1131 
   1132     if ( (status = sBluetoothSocketInterface->connect((bt_bdaddr_t *) addr, (btsock_type_t) type,
   1133                        (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) {
   1134         ALOGE("Socket connection failed: %d", status);
   1135         goto Fail;
   1136     }
   1137 
   1138 
   1139     if (socket_fd < 0) {
   1140         ALOGE("Fail to creat file descriptor on socket fd");
   1141         goto Fail;
   1142     }
   1143     env->ReleaseByteArrayElements(address, addr, 0);
   1144     env->ReleaseByteArrayElements(uuidObj, uuid, 0);
   1145     return socket_fd;
   1146 
   1147 Fail:
   1148     if (addr) env->ReleaseByteArrayElements(address, addr, 0);
   1149     if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
   1150 
   1151     return -1;
   1152 }
   1153 
   1154 static int createSocketChannelNative(JNIEnv *env, jobject object, jint type,
   1155                                      jstring name_str, jbyteArray uuidObj, jint channel, jint flag) {
   1156     const char *service_name;
   1157     jbyte *uuid = NULL;
   1158     int socket_fd;
   1159     bt_status_t status;
   1160 
   1161     if (!sBluetoothSocketInterface) return -1;
   1162 
   1163     ALOGV("%s: SOCK FLAG = %x", __FUNCTION__, flag);
   1164 
   1165     service_name = env->GetStringUTFChars(name_str, NULL);
   1166 
   1167     uuid = env->GetByteArrayElements(uuidObj, NULL);
   1168     if (!uuid) {
   1169         ALOGE("failed to get uuid");
   1170         goto Fail;
   1171     }
   1172     if ( (status = sBluetoothSocketInterface->listen((btsock_type_t) type, service_name,
   1173                        (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) {
   1174         ALOGE("Socket listen failed: %d", status);
   1175         goto Fail;
   1176     }
   1177 
   1178     if (socket_fd < 0) {
   1179         ALOGE("Fail to creat file descriptor on socket fd");
   1180         goto Fail;
   1181     }
   1182     if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
   1183     if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
   1184     return socket_fd;
   1185 
   1186 Fail:
   1187     if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
   1188     if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
   1189 
   1190     return -1;
   1191 }
   1192 
   1193 static jboolean configHciSnoopLogNative(JNIEnv* env, jobject obj, jboolean enable) {
   1194     ALOGV("%s:",__FUNCTION__);
   1195 
   1196     jboolean result = JNI_FALSE;
   1197 
   1198     if (!sBluetoothInterface) return result;
   1199 
   1200     int ret = sBluetoothInterface->config_hci_snoop_log(enable);
   1201 
   1202     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
   1203 
   1204     return result;
   1205 }
   1206 
   1207 static int readEnergyInfo()
   1208 {
   1209     ALOGV("%s:",__FUNCTION__);
   1210     jboolean result = JNI_FALSE;
   1211     if (!sBluetoothInterface) return result;
   1212     int ret = sBluetoothInterface->read_energy_info();
   1213     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
   1214     return result;
   1215 }
   1216 
   1217 static JNINativeMethod sMethods[] = {
   1218     /* name, signature, funcPtr */
   1219     {"classInitNative", "()V", (void *) classInitNative},
   1220     {"initNative", "()Z", (void *) initNative},
   1221     {"cleanupNative", "()V", (void*) cleanupNative},
   1222     {"enableNative", "()Z",  (void*) enableNative},
   1223     {"disableNative", "()Z",  (void*) disableNative},
   1224     {"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative},
   1225     {"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative},
   1226     {"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative},
   1227     {"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative},
   1228     {"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative},
   1229     {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative},
   1230     {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative},
   1231     {"createBondNative", "([BI)Z", (void*) createBondNative},
   1232     {"removeBondNative", "([B)Z", (void*) removeBondNative},
   1233     {"cancelBondNative", "([B)Z", (void*) cancelBondNative},
   1234     {"getConnectionStateNative", "([B)I", (void*) getConnectionStateNative},
   1235     {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative},
   1236     {"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative},
   1237     {"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative},
   1238     {"getRemoteMasInstancesNative", "([B)Z", (void*) getRemoteMasInstancesNative},
   1239     {"connectSocketNative", "([BI[BII)I", (void*) connectSocketNative},
   1240     {"createSocketChannelNative", "(ILjava/lang/String;[BII)I",
   1241      (void*) createSocketChannelNative},
   1242     {"configHciSnoopLogNative", "(Z)Z", (void*) configHciSnoopLogNative},
   1243     {"alarmFiredNative", "()V", (void *) alarmFiredNative},
   1244     {"readEnergyInfo", "()I", (void*) readEnergyInfo},
   1245 };
   1246 
   1247 int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env)
   1248 {
   1249     return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService",
   1250                                     sMethods, NELEM(sMethods));
   1251 }
   1252 
   1253 } /* namespace android */
   1254 
   1255 
   1256 /*
   1257  * JNI Initialization
   1258  */
   1259 jint JNI_OnLoad(JavaVM *jvm, void *reserved)
   1260 {
   1261     JNIEnv *e;
   1262     int status;
   1263 
   1264     ALOGV("Bluetooth Adapter Service : loading JNI\n");
   1265 
   1266     // Check JNI version
   1267     if (jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) {
   1268         ALOGE("JNI version mismatch error");
   1269         return JNI_ERR;
   1270     }
   1271 
   1272     if ((status = android::register_com_android_bluetooth_btservice_AdapterService(e)) < 0) {
   1273         ALOGE("jni adapter service registration failure, status: %d", status);
   1274         return JNI_ERR;
   1275     }
   1276 
   1277     if ((status = android::register_com_android_bluetooth_hfp(e)) < 0) {
   1278         ALOGE("jni hfp registration failure, status: %d", status);
   1279         return JNI_ERR;
   1280     }
   1281 
   1282     if ((status = android::register_com_android_bluetooth_hfpclient(e)) < 0) {
   1283         ALOGE("jni hfp client registration failure, status: %d", status);
   1284         return JNI_ERR;
   1285     }
   1286 
   1287     if ((status = android::register_com_android_bluetooth_a2dp(e)) < 0) {
   1288         ALOGE("jni a2dp source registration failure: %d", status);
   1289         return JNI_ERR;
   1290     }
   1291 
   1292     if ((status = android::register_com_android_bluetooth_a2dp_sink(e)) < 0) {
   1293         ALOGE("jni a2dp sink registration failure: %d", status);
   1294         return JNI_ERR;
   1295     }
   1296 
   1297     if ((status = android::register_com_android_bluetooth_avrcp(e)) < 0) {
   1298         ALOGE("jni avrcp target registration failure: %d", status);
   1299         return JNI_ERR;
   1300     }
   1301 
   1302     if ((status = android::register_com_android_bluetooth_avrcp_controller(e)) < 0) {
   1303         ALOGE("jni avrcp controller registration failure: %d", status);
   1304         return JNI_ERR;
   1305     }
   1306 
   1307     if ((status = android::register_com_android_bluetooth_hid(e)) < 0) {
   1308         ALOGE("jni hid registration failure: %d", status);
   1309         return JNI_ERR;
   1310     }
   1311 
   1312     if ((status = android::register_com_android_bluetooth_hdp(e)) < 0) {
   1313         ALOGE("jni hdp registration failure: %d", status);
   1314         return JNI_ERR;
   1315     }
   1316 
   1317     if ((status = android::register_com_android_bluetooth_pan(e)) < 0) {
   1318         ALOGE("jni pan registration failure: %d", status);
   1319         return JNI_ERR;
   1320     }
   1321 
   1322     if ((status = android::register_com_android_bluetooth_gatt(e)) < 0) {
   1323         ALOGE("jni gatt registration failure: %d", status);
   1324         return JNI_ERR;
   1325     }
   1326     return JNI_VERSION_1_6;
   1327 }
   1328