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