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