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