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