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