• 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 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