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