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