1 /*
2  * Copyright (C) 2016-2017 The Linux Foundation
3  * Copyright (C) 2012 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #define LOG_TAG "BluetoothServiceJni"
19 
20 #include <dlfcn.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <hardware/bluetooth.h>
24 #include <nativehelper/JNIPlatformHelp.h>
25 #include <pthread.h>
26 #include <string.h>
27 #include <sys/prctl.h>
28 #include <sys/stat.h>
29 
30 #include <shared_mutex>
31 
32 #include "com_android_bluetooth.h"
33 #include "hardware/bt_sock.h"
34 #include "os/logging/log_adapter.h"
35 #include "utils/misc.h"
36 
37 using bluetooth::Uuid;
38 extern bt_interface_t bluetoothInterface;
39 
40 namespace fmt {
41 template <>
42 struct formatter<bt_state_t> : enum_formatter<bt_state_t> {};
43 template <>
44 struct formatter<bt_discovery_state_t> : enum_formatter<bt_discovery_state_t> {
45 };
46 }  // namespace fmt
47 
from_java_uuid(jlong uuid_msb,jlong uuid_lsb)48 static Uuid from_java_uuid(jlong uuid_msb, jlong uuid_lsb) {
49   std::array<uint8_t, Uuid::kNumBytes128> uu;
50   for (int i = 0; i < 8; i++) {
51     uu[7 - i] = (uuid_msb >> (8 * i)) & 0xFF;
52     uu[15 - i] = (uuid_lsb >> (8 * i)) & 0xFF;
53   }
54   return Uuid::From128BitBE(uu);
55 }
56 
57 namespace android {
58 // Both
59 
60 #define TRANSPORT_AUTO 0
61 #define TRANSPORT_BREDR 1
62 #define TRANSPORT_LE 2
63 
64 #define BLE_ADDR_PUBLIC 0x00
65 #define BLE_ADDR_RANDOM 0x01
66 
67 const jint INVALID_FD = -1;
68 const jint INVALID_CID = -1;
69 
70 static jmethodID method_oobDataReceivedCallback;
71 static jmethodID method_stateChangeCallback;
72 static jmethodID method_adapterPropertyChangedCallback;
73 static jmethodID method_devicePropertyChangedCallback;
74 static jmethodID method_deviceFoundCallback;
75 static jmethodID method_pinRequestCallback;
76 static jmethodID method_sspRequestCallback;
77 static jmethodID method_bondStateChangeCallback;
78 static jmethodID method_addressConsolidateCallback;
79 static jmethodID method_leAddressAssociateCallback;
80 static jmethodID method_aclStateChangeCallback;
81 static jmethodID method_discoveryStateChangeCallback;
82 static jmethodID method_linkQualityReportCallback;
83 static jmethodID method_switchBufferSizeCallback;
84 static jmethodID method_switchCodecCallback;
85 static jmethodID method_acquireWakeLock;
86 static jmethodID method_releaseWakeLock;
87 static jmethodID method_energyInfo;
88 static jmethodID method_keyMissingCallback;
89 
90 static struct {
91   jclass clazz;
92   jmethodID constructor;
93 } android_bluetooth_UidTraffic;
94 
95 static const bt_interface_t* sBluetoothInterface = NULL;
96 static const btsock_interface_t* sBluetoothSocketInterface = NULL;
97 static JavaVM* vm = NULL;
98 static JNIEnv* callbackEnv = NULL;
99 static pthread_t sCallbackThread;
100 static bool sHaveCallbackThread;
101 
102 static jobject sJniAdapterServiceObj;
103 static jobject sJniCallbacksObj;
104 static std::shared_timed_mutex jniObjMutex;
105 static jfieldID sJniCallbacksField;
106 
getBluetoothInterface()107 const bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; }
108 
getCallbackEnv()109 JNIEnv* getCallbackEnv() { return callbackEnv; }
110 
isCallbackThread()111 bool isCallbackThread() {
112   return sHaveCallbackThread && pthread_equal(sCallbackThread, pthread_self());
113 }
114 
adapter_state_change_callback(bt_state_t status)115 static void adapter_state_change_callback(bt_state_t status) {
116   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
117   if (!sJniCallbacksObj) {
118     log::error("JNI obj is null. Failed to call JNI callback");
119     return;
120   }
121 
122   CallbackEnv sCallbackEnv(__func__);
123   if (!sCallbackEnv.valid()) return;
124   log::verbose("Status is: {}", status);
125 
126   sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback,
127                                (jint)status);
128 }
129 
get_properties(int num_properties,bt_property_t * properties,jintArray * types,jobjectArray * props)130 static int get_properties(int num_properties, bt_property_t* properties,
131                           jintArray* types, jobjectArray* props) {
132   for (int i = 0; i < num_properties; i++) {
133     ScopedLocalRef<jbyteArray> propVal(
134         callbackEnv, callbackEnv->NewByteArray(properties[i].len));
135     if (!propVal.get()) {
136       log::error("Error while allocation of array");
137       return -1;
138     }
139 
140     callbackEnv->SetByteArrayRegion(propVal.get(), 0, properties[i].len,
141                                     (jbyte*)properties[i].val);
142     callbackEnv->SetObjectArrayElement(*props, i, propVal.get());
143     callbackEnv->SetIntArrayRegion(*types, i, 1, (jint*)&properties[i].type);
144   }
145   return 0;
146 }
147 
adapter_properties_callback(bt_status_t status,int num_properties,bt_property_t * properties)148 static void adapter_properties_callback(bt_status_t status, int num_properties,
149                                         bt_property_t* properties) {
150   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
151   if (!sJniCallbacksObj) {
152     log::error("JNI obj is null. Failed to call JNI callback");
153     return;
154   }
155 
156   CallbackEnv sCallbackEnv(__func__);
157   if (!sCallbackEnv.valid()) return;
158 
159   log::verbose("Status is: {}, Properties: {}", bt_status_text(status),
160                num_properties);
161 
162   if (status != BT_STATUS_SUCCESS) {
163     log::error("Status {} is incorrect", bt_status_text(status));
164     return;
165   }
166 
167   ScopedLocalRef<jbyteArray> val(
168       sCallbackEnv.get(),
169       (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
170   if (!val.get()) {
171     log::error("Error allocating byteArray");
172     return;
173   }
174 
175   ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
176                                 sCallbackEnv->GetObjectClass(val.get()));
177 
178   /* (BT) Initialize the jobjectArray and jintArray here itself and send the
179    initialized array pointers alone to get_properties */
180 
181   ScopedLocalRef<jobjectArray> props(
182       sCallbackEnv.get(),
183       sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
184   if (!props.get()) {
185     log::error("Error allocating object Array for properties");
186     return;
187   }
188 
189   ScopedLocalRef<jintArray> types(
190       sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
191   if (!types.get()) {
192     log::error("Error allocating int Array for values");
193     return;
194   }
195 
196   jintArray typesPtr = types.get();
197   jobjectArray propsPtr = props.get();
198   if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
199     return;
200   }
201 
202   sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
203                                method_adapterPropertyChangedCallback,
204                                types.get(), props.get());
205 }
206 
remote_device_properties_callback(bt_status_t status,RawAddress * bd_addr,int num_properties,bt_property_t * properties)207 static void remote_device_properties_callback(bt_status_t status,
208                                               RawAddress* bd_addr,
209                                               int num_properties,
210                                               bt_property_t* properties) {
211   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
212   if (!sJniCallbacksObj) {
213     log::error("JNI obj is null. Failed to call JNI callback");
214     return;
215   }
216 
217   CallbackEnv sCallbackEnv(__func__);
218   if (!sCallbackEnv.valid()) return;
219 
220   log::verbose("Device: {}, Status: {}, Properties: {}",
221                ADDRESS_TO_LOGGABLE_STR(*bd_addr), bt_status_text(status),
222                num_properties);
223 
224   if (status != BT_STATUS_SUCCESS) {
225     log::error("Status {} is incorrect", bt_status_text(status));
226     return;
227   }
228 
229   ScopedLocalRef<jbyteArray> val(
230       sCallbackEnv.get(),
231       (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
232   if (!val.get()) {
233     log::error("Error allocating byteArray");
234     return;
235   }
236 
237   ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
238                                 sCallbackEnv->GetObjectClass(val.get()));
239 
240   /* Initialize the jobjectArray and jintArray here itself and send the
241    initialized array pointers alone to get_properties */
242 
243   ScopedLocalRef<jobjectArray> props(
244       sCallbackEnv.get(),
245       sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
246   if (!props.get()) {
247     log::error("Error allocating object Array for properties");
248     return;
249   }
250 
251   ScopedLocalRef<jintArray> types(
252       sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
253   if (!types.get()) {
254     log::error("Error allocating int Array for values");
255     return;
256   }
257 
258   ScopedLocalRef<jbyteArray> addr(
259       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
260   if (!addr.get()) {
261     log::error("Error while allocation byte array");
262     return;
263   }
264 
265   sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
266                                    (jbyte*)bd_addr);
267 
268   jintArray typesPtr = types.get();
269   jobjectArray propsPtr = props.get();
270   if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
271     return;
272   }
273 
274   sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
275                                method_devicePropertyChangedCallback, addr.get(),
276                                types.get(), props.get());
277 }
278 
device_found_callback(int num_properties,bt_property_t * properties)279 static void device_found_callback(int num_properties,
280                                   bt_property_t* properties) {
281   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
282   if (!sJniCallbacksObj) {
283     log::error("JNI obj is null. Failed to call JNI callback");
284     return;
285   }
286 
287   CallbackEnv sCallbackEnv(__func__);
288   if (!sCallbackEnv.valid()) return;
289 
290   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), NULL);
291   int addr_index;
292   for (int i = 0; i < num_properties; i++) {
293     if (properties[i].type == BT_PROPERTY_BDADDR) {
294       addr.reset(sCallbackEnv->NewByteArray(properties[i].len));
295       if (!addr.get()) {
296         log::error("Address is NULL (unable to allocate)");
297         return;
298       }
299       sCallbackEnv->SetByteArrayRegion(addr.get(), 0, properties[i].len,
300                                        (jbyte*)properties[i].val);
301       addr_index = i;
302     }
303   }
304   if (!addr.get()) {
305     log::error("Address is NULL");
306     return;
307   }
308 
309   log::verbose("Properties: {}, Address: {}", num_properties,
310                *(RawAddress*)properties[addr_index].val);
311 
312   remote_device_properties_callback(BT_STATUS_SUCCESS,
313                                     (RawAddress*)properties[addr_index].val,
314                                     num_properties, properties);
315 
316   sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback,
317                                addr.get());
318 }
319 
bond_state_changed_callback(bt_status_t status,RawAddress * bd_addr,bt_bond_state_t state,int fail_reason)320 static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
321                                         bt_bond_state_t state,
322                                         int fail_reason) {
323   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
324   if (!sJniCallbacksObj) {
325     log::error("JNI obj is null. Failed to call JNI callback");
326     return;
327   }
328 
329   CallbackEnv sCallbackEnv(__func__);
330   if (!sCallbackEnv.valid()) return;
331 
332   if (!bd_addr) {
333     log::error("Address is null");
334     return;
335   }
336 
337   ScopedLocalRef<jbyteArray> addr(
338       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
339   if (!addr.get()) {
340     log::error("Address allocation failed");
341     return;
342   }
343   sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
344                                    (jbyte*)bd_addr);
345 
346   sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback,
347                                (jint)status, addr.get(), (jint)state,
348                                (jint)fail_reason);
349 }
350 
address_consolidate_callback(RawAddress * main_bd_addr,RawAddress * secondary_bd_addr)351 static void address_consolidate_callback(RawAddress* main_bd_addr,
352                                          RawAddress* secondary_bd_addr) {
353   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
354   if (!sJniCallbacksObj) {
355     log::error("JNI obj is null. Failed to call JNI callback");
356     return;
357   }
358 
359   CallbackEnv sCallbackEnv(__func__);
360 
361   ScopedLocalRef<jbyteArray> main_addr(
362       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
363   if (!main_addr.get()) {
364     log::error("Address allocation failed");
365     return;
366   }
367   sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress),
368                                    (jbyte*)main_bd_addr);
369 
370   ScopedLocalRef<jbyteArray> secondary_addr(
371       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
372   if (!secondary_addr.get()) {
373     log::error("Address allocation failed");
374     return;
375   }
376 
377   sCallbackEnv->SetByteArrayRegion(secondary_addr.get(), 0, sizeof(RawAddress),
378                                    (jbyte*)secondary_bd_addr);
379 
380   sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
381                                method_addressConsolidateCallback,
382                                main_addr.get(), secondary_addr.get());
383 }
384 
le_address_associate_callback(RawAddress * main_bd_addr,RawAddress * secondary_bd_addr)385 static void le_address_associate_callback(RawAddress* main_bd_addr,
386                                           RawAddress* secondary_bd_addr) {
387   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
388   if (!sJniCallbacksObj) {
389     log::error("JNI obj is null. Failed to call JNI callback");
390     return;
391   }
392 
393   CallbackEnv sCallbackEnv(__func__);
394 
395   ScopedLocalRef<jbyteArray> main_addr(
396       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
397   if (!main_addr.get()) {
398     log::error("Address allocation failed");
399     return;
400   }
401   sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress),
402                                    (jbyte*)main_bd_addr);
403 
404   ScopedLocalRef<jbyteArray> secondary_addr(
405       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
406   if (!secondary_addr.get()) {
407     log::error("Address allocation failed");
408     return;
409   }
410 
411   sCallbackEnv->SetByteArrayRegion(secondary_addr.get(), 0, sizeof(RawAddress),
412                                    (jbyte*)secondary_bd_addr);
413 
414   sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
415                                method_leAddressAssociateCallback,
416                                main_addr.get(), secondary_addr.get());
417 }
418 
acl_state_changed_callback(bt_status_t status,RawAddress * bd_addr,bt_acl_state_t state,int transport_link_type,bt_hci_error_code_t hci_reason,bt_conn_direction_t,uint16_t acl_handle)419 static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
420                                        bt_acl_state_t state,
421                                        int transport_link_type,
422                                        bt_hci_error_code_t hci_reason,
423                                        bt_conn_direction_t /* direction */,
424                                        uint16_t acl_handle) {
425   if (!bd_addr) {
426     log::error("Address is null");
427     return;
428   }
429 
430   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
431   if (!sJniCallbacksObj) {
432     log::error("JNI obj is null. Failed to call JNI callback");
433     return;
434   }
435 
436   CallbackEnv sCallbackEnv(__func__);
437   if (!sCallbackEnv.valid()) return;
438 
439   ScopedLocalRef<jbyteArray> addr(
440       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
441   if (!addr.get()) {
442     log::error("Address allocation failed");
443     return;
444   }
445   sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
446                                    (jbyte*)bd_addr);
447 
448   sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback,
449                                (jint)status, addr.get(), (jint)state,
450                                (jint)transport_link_type, (jint)hci_reason,
451                                (jint)acl_handle);
452 }
453 
discovery_state_changed_callback(bt_discovery_state_t state)454 static void discovery_state_changed_callback(bt_discovery_state_t state) {
455   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
456   if (!sJniCallbacksObj) {
457     log::error("JNI obj is null. Failed to call JNI callback");
458     return;
459   }
460 
461   CallbackEnv sCallbackEnv(__func__);
462   if (!sCallbackEnv.valid()) return;
463 
464   log::verbose("DiscoveryState:{}", state);
465 
466   sCallbackEnv->CallVoidMethod(
467       sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state);
468 }
469 
pin_request_callback(RawAddress * bd_addr,bt_bdname_t * bdname,uint32_t cod,bool min_16_digits)470 static void pin_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
471                                  uint32_t cod, bool min_16_digits) {
472   if (!bd_addr) {
473     log::error("Address is null");
474     return;
475   }
476 
477   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
478   if (!sJniCallbacksObj) {
479     log::error("JNI obj is null. Failed to call JNI callback");
480     return;
481   }
482 
483   CallbackEnv sCallbackEnv(__func__);
484   if (!sCallbackEnv.valid()) return;
485 
486   ScopedLocalRef<jbyteArray> addr(
487       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
488   if (!addr.get()) {
489     log::error("Error while allocating");
490     return;
491   }
492 
493   sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
494                                    (jbyte*)bd_addr);
495 
496   ScopedLocalRef<jbyteArray> devname(
497       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)));
498   if (!devname.get()) {
499     log::error("Error while allocating");
500     return;
501   }
502 
503   sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t),
504                                    (jbyte*)bdname);
505 
506   sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback,
507                                addr.get(), devname.get(), cod, min_16_digits);
508 }
509 
ssp_request_callback(RawAddress * bd_addr,bt_ssp_variant_t pairing_variant,uint32_t pass_key)510 static void ssp_request_callback(RawAddress* bd_addr,
511                                  bt_ssp_variant_t pairing_variant,
512                                  uint32_t pass_key) {
513   if (!bd_addr) {
514     log::error("Address is null");
515     return;
516   }
517 
518   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
519   if (!sJniCallbacksObj) {
520     log::error("JNI obj is null. Failed to call JNI callback");
521     return;
522   }
523 
524   CallbackEnv sCallbackEnv(__func__);
525   if (!sCallbackEnv.valid()) return;
526 
527   ScopedLocalRef<jbyteArray> addr(
528       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
529   if (!addr.get()) {
530     log::error("Error while allocating");
531     return;
532   }
533 
534   sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
535                                    (jbyte*)bd_addr);
536 
537   sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback,
538                                addr.get(), (jint)pairing_variant, pass_key);
539 }
540 
createClassicOobDataObject(JNIEnv * env,bt_oob_data_t oob_data)541 static jobject createClassicOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) {
542   log::verbose("");
543   jmethodID classicBuilderConstructor;
544   jmethodID setRMethod;
545   jmethodID setNameMethod;
546   jmethodID buildMethod;
547 
548   const JNIJavaMethod javaMethods[] = {
549       {"<init>", "([B[B[B)V", &classicBuilderConstructor},
550       {"setRandomizerHash", "([B)Landroid/bluetooth/OobData$ClassicBuilder;",
551        &setRMethod},
552       {"setDeviceName", "([B)Landroid/bluetooth/OobData$ClassicBuilder;",
553        &setNameMethod},
554       {"build", "()Landroid/bluetooth/OobData;", &buildMethod},
555   };
556   GET_JAVA_METHODS(env, "android/bluetooth/OobData$ClassicBuilder",
557                    javaMethods);
558 
559   jbyteArray confirmationHash = env->NewByteArray(OOB_C_SIZE);
560   env->SetByteArrayRegion(confirmationHash, 0, OOB_C_SIZE,
561                           reinterpret_cast<jbyte*>(oob_data.c));
562 
563   jbyteArray oobDataLength = env->NewByteArray(OOB_DATA_LEN_SIZE);
564   env->SetByteArrayRegion(oobDataLength, 0, OOB_DATA_LEN_SIZE,
565                           reinterpret_cast<jbyte*>(oob_data.oob_data_length));
566 
567   jbyteArray address = env->NewByteArray(OOB_ADDRESS_SIZE);
568   env->SetByteArrayRegion(address, 0, OOB_ADDRESS_SIZE,
569                           reinterpret_cast<jbyte*>(oob_data.address));
570 
571   jclass classicBuilderClass =
572       env->FindClass("android/bluetooth/OobData$ClassicBuilder");
573 
574   jobject oobDataClassicBuilder =
575       env->NewObject(classicBuilderClass, classicBuilderConstructor,
576                      confirmationHash, oobDataLength, address);
577 
578   env->DeleteLocalRef(classicBuilderClass);
579 
580   jbyteArray randomizerHash = env->NewByteArray(OOB_R_SIZE);
581   env->SetByteArrayRegion(randomizerHash, 0, OOB_R_SIZE,
582                           reinterpret_cast<jbyte*>(oob_data.r));
583 
584   oobDataClassicBuilder =
585       env->CallObjectMethod(oobDataClassicBuilder, setRMethod, randomizerHash);
586 
587   int name_char_count = 0;
588   for (int i = 0; i < OOB_NAME_MAX_SIZE; i++) {
589     if (oob_data.device_name[i] == 0) {
590       name_char_count = i;
591       break;
592     }
593   }
594 
595   jbyteArray deviceName = env->NewByteArray(name_char_count);
596   env->SetByteArrayRegion(deviceName, 0, name_char_count,
597                           reinterpret_cast<jbyte*>(oob_data.device_name));
598 
599   oobDataClassicBuilder =
600       env->CallObjectMethod(oobDataClassicBuilder, setNameMethod, deviceName);
601 
602   return env->CallObjectMethod(oobDataClassicBuilder, buildMethod);
603 }
604 
createLeOobDataObject(JNIEnv * env,bt_oob_data_t oob_data)605 static jobject createLeOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) {
606   log::verbose("");
607 
608   jmethodID leBuilderConstructor;
609   jmethodID setRMethod;
610   jmethodID setNameMethod;
611   jmethodID buildMethod;
612 
613   const JNIJavaMethod javaMethods[] = {
614       {"<init>", "([B[BI)V", &leBuilderConstructor},
615       {"setRandomizerHash", "([B)Landroid/bluetooth/OobData$LeBuilder;",
616        &setRMethod},
617       {"setDeviceName", "([B)Landroid/bluetooth/OobData$LeBuilder;",
618        &setNameMethod},
619       {"build", "()Landroid/bluetooth/OobData;", &buildMethod},
620   };
621   GET_JAVA_METHODS(env, "android/bluetooth/OobData$LeBuilder", javaMethods);
622 
623   jbyteArray confirmationHash = env->NewByteArray(OOB_C_SIZE);
624   env->SetByteArrayRegion(confirmationHash, 0, OOB_C_SIZE,
625                           reinterpret_cast<jbyte*>(oob_data.c));
626 
627   jbyteArray address = env->NewByteArray(OOB_ADDRESS_SIZE);
628   env->SetByteArrayRegion(address, 0, OOB_ADDRESS_SIZE,
629                           reinterpret_cast<jbyte*>(oob_data.address));
630 
631   jint le_role = (jint)oob_data.le_device_role;
632 
633   jclass leBuilderClass = env->FindClass("android/bluetooth/OobData$LeBuilder");
634 
635   jobject oobDataLeBuilder = env->NewObject(
636       leBuilderClass, leBuilderConstructor, confirmationHash, address, le_role);
637 
638   env->DeleteLocalRef(leBuilderClass);
639 
640   jbyteArray randomizerHash = env->NewByteArray(OOB_R_SIZE);
641   env->SetByteArrayRegion(randomizerHash, 0, OOB_R_SIZE,
642                           reinterpret_cast<jbyte*>(oob_data.r));
643 
644   oobDataLeBuilder =
645       env->CallObjectMethod(oobDataLeBuilder, setRMethod, randomizerHash);
646 
647   int name_char_count = 0;
648   for (int i = 0; i < OOB_NAME_MAX_SIZE; i++) {
649     if (oob_data.device_name[i] == 0) {
650       name_char_count = i;
651       break;
652     }
653   }
654 
655   jbyteArray deviceName = env->NewByteArray(name_char_count);
656   env->SetByteArrayRegion(deviceName, 0, name_char_count,
657                           reinterpret_cast<jbyte*>(oob_data.device_name));
658 
659   oobDataLeBuilder =
660       env->CallObjectMethod(oobDataLeBuilder, setNameMethod, deviceName);
661 
662   return env->CallObjectMethod(oobDataLeBuilder, buildMethod);
663 }
664 
generate_local_oob_data_callback(tBT_TRANSPORT transport,bt_oob_data_t oob_data)665 static void generate_local_oob_data_callback(tBT_TRANSPORT transport,
666                                              bt_oob_data_t oob_data) {
667   log::verbose("");
668 
669   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
670   if (!sJniCallbacksObj) {
671     log::error("JNI obj is null. Failed to call JNI callback");
672     return;
673   }
674 
675   CallbackEnv sCallbackEnv(__func__);
676   if (!sCallbackEnv.valid()) return;
677 
678   if (transport == TRANSPORT_BREDR) {
679     sCallbackEnv->CallVoidMethod(
680         sJniCallbacksObj, method_oobDataReceivedCallback, (jint)transport,
681         ((oob_data.is_valid)
682              ? createClassicOobDataObject(sCallbackEnv.get(), oob_data)
683              : nullptr));
684   } else if (transport == TRANSPORT_LE) {
685     sCallbackEnv->CallVoidMethod(
686         sJniCallbacksObj, method_oobDataReceivedCallback, (jint)transport,
687         ((oob_data.is_valid)
688              ? createLeOobDataObject(sCallbackEnv.get(), oob_data)
689              : nullptr));
690   } else {
691     // TRANSPORT_AUTO is a concept, however, the host stack doesn't fully
692     // implement it So passing it from the java layer is currently useless until
693     // the implementation and concept of TRANSPORT_AUTO is fleshed out.
694     log::error("TRANSPORT: {} not implemented", transport);
695     sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
696                                  method_oobDataReceivedCallback,
697                                  (jint)transport, nullptr);
698   }
699 }
700 
link_quality_report_callback(uint64_t timestamp,int report_id,int rssi,int snr,int retransmission_count,int packets_not_receive_count,int negative_acknowledgement_count)701 static void link_quality_report_callback(
702     uint64_t timestamp, int report_id, int rssi, int snr,
703     int retransmission_count, int packets_not_receive_count,
704     int negative_acknowledgement_count) {
705   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
706   if (!sJniCallbacksObj) {
707     log::error("JNI obj is null. Failed to call JNI callback");
708     return;
709   }
710 
711   CallbackEnv sCallbackEnv(__func__);
712   if (!sCallbackEnv.valid()) return;
713 
714   log::verbose("LinkQualityReportCallback: {} {} {} {} {} {}", report_id, rssi,
715                snr, retransmission_count, packets_not_receive_count,
716                negative_acknowledgement_count);
717 
718   sCallbackEnv->CallVoidMethod(
719       sJniCallbacksObj, method_linkQualityReportCallback,
720       (jlong)timestamp, (jint)report_id, (jint)rssi, (jint)snr,
721       (jint)retransmission_count, (jint)packets_not_receive_count,
722       (jint)negative_acknowledgement_count);
723 }
724 
switch_buffer_size_callback(bool is_low_latency_buffer_size)725 static void switch_buffer_size_callback(bool is_low_latency_buffer_size) {
726   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
727   if (!sJniCallbacksObj) {
728     log::error("JNI obj is null. Failed to call JNI callback");
729     return;
730   }
731 
732   CallbackEnv sCallbackEnv(__func__);
733   if (!sCallbackEnv.valid()) return;
734 
735   log::verbose("SwitchBufferSizeCallback: {}", is_low_latency_buffer_size);
736 
737   sCallbackEnv->CallVoidMethod(
738       sJniCallbacksObj, method_switchBufferSizeCallback,
739       (jboolean)is_low_latency_buffer_size);
740 }
741 
switch_codec_callback(bool is_low_latency_buffer_size)742 static void switch_codec_callback(bool is_low_latency_buffer_size) {
743   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
744   if (!sJniCallbacksObj) {
745     log::error("JNI obj is null. Failed to call JNI callback");
746     return;
747   }
748 
749   CallbackEnv sCallbackEnv(__func__);
750   if (!sCallbackEnv.valid()) return;
751 
752   log::verbose("SwitchCodecCallback: {}", is_low_latency_buffer_size);
753 
754   sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_switchCodecCallback,
755                                (jboolean)is_low_latency_buffer_size);
756 }
757 
le_rand_callback(uint64_t)758 static void le_rand_callback(uint64_t /* random */) {
759   // Android doesn't support the LeRand API.
760 }
761 
key_missing_callback(const RawAddress bd_addr)762 static void key_missing_callback(const RawAddress bd_addr) {
763   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
764   if (!sJniCallbacksObj) {
765     log::error("JNI obj is null. Failed to call JNI callback");
766     return;
767   }
768 
769   CallbackEnv sCallbackEnv(__func__);
770   if (!sCallbackEnv.valid()) return;
771 
772   ScopedLocalRef<jbyteArray> addr(
773       sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
774   if (!addr.get()) {
775     log::error("Address allocation failed");
776     return;
777   }
778   sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
779                                    (jbyte*)&bd_addr);
780 
781   sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_keyMissingCallback,
782                                addr.get());
783 }
784 
callback_thread_event(bt_cb_thread_evt event)785 static void callback_thread_event(bt_cb_thread_evt event) {
786   if (event == ASSOCIATE_JVM) {
787     JavaVMAttachArgs args;
788     char name[] = "BT Service Callback Thread";
789     args.version = JNI_VERSION_1_6;
790     args.name = name;
791     args.group = NULL;
792     vm->AttachCurrentThread(&callbackEnv, &args);
793     sHaveCallbackThread = true;
794     sCallbackThread = pthread_self();
795     log::verbose("Callback thread attached: {}", fmt::ptr(callbackEnv));
796   } else if (event == DISASSOCIATE_JVM) {
797     if (!isCallbackThread()) {
798       log::error("Callback: '' is not called on the correct thread");
799       return;
800     }
801     vm->DetachCurrentThread();
802     sHaveCallbackThread = false;
803     callbackEnv = NULL;
804   }
805 }
806 
dut_mode_recv_callback(uint16_t,uint8_t *,uint8_t)807 static void dut_mode_recv_callback(uint16_t /* opcode */, uint8_t* /* buf */,
808                                    uint8_t /* len */) {}
809 
le_test_mode_recv_callback(bt_status_t status,uint16_t packet_count)810 static void le_test_mode_recv_callback(bt_status_t status,
811                                        uint16_t packet_count) {
812   log::verbose("status:{} packet_count:{}", bt_status_text(status),
813                packet_count);
814 }
815 
energy_info_recv_callback(bt_activity_energy_info * p_energy_info,bt_uid_traffic_t * uid_data)816 static void energy_info_recv_callback(bt_activity_energy_info* p_energy_info,
817                                       bt_uid_traffic_t* uid_data) {
818   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
819   if (!sJniAdapterServiceObj) {
820     log::error("JNI obj is null. Failed to call JNI callback");
821     return;
822   }
823 
824   CallbackEnv sCallbackEnv(__func__);
825   if (!sCallbackEnv.valid()) return;
826 
827   jsize len = 0;
828   for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
829     len++;
830   }
831 
832   ScopedLocalRef<jobjectArray> array(
833       sCallbackEnv.get(), sCallbackEnv->NewObjectArray(
834                               len, android_bluetooth_UidTraffic.clazz, NULL));
835   jsize i = 0;
836   for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
837     ScopedLocalRef<jobject> uidObj(
838         sCallbackEnv.get(),
839         sCallbackEnv->NewObject(android_bluetooth_UidTraffic.clazz,
840                                 android_bluetooth_UidTraffic.constructor,
841                                 (jint)data->app_uid, (jlong)data->rx_bytes,
842                                 (jlong)data->tx_bytes));
843     sCallbackEnv->SetObjectArrayElement(array.get(), i++, uidObj.get());
844   }
845 
846   sCallbackEnv->CallVoidMethod(
847       sJniCallbacksObj, method_energyInfo, p_energy_info->status,
848       p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time,
849       p_energy_info->idle_time, p_energy_info->energy_used, array.get());
850 }
851 
852 static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks),
853                                              adapter_state_change_callback,
854                                              adapter_properties_callback,
855                                              remote_device_properties_callback,
856                                              device_found_callback,
857                                              discovery_state_changed_callback,
858                                              pin_request_callback,
859                                              ssp_request_callback,
860                                              bond_state_changed_callback,
861                                              address_consolidate_callback,
862                                              le_address_associate_callback,
863                                              acl_state_changed_callback,
864                                              callback_thread_event,
865                                              dut_mode_recv_callback,
866                                              le_test_mode_recv_callback,
867                                              energy_info_recv_callback,
868                                              link_quality_report_callback,
869                                              generate_local_oob_data_callback,
870                                              switch_buffer_size_callback,
871                                              switch_codec_callback,
872                                              le_rand_callback,
873                                              key_missing_callback};
874 
875 class JNIThreadAttacher {
876  public:
JNIThreadAttacher(JavaVM * vm)877   JNIThreadAttacher(JavaVM* vm) : vm_(vm), env_(nullptr) {
878     status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6);
879 
880     if (status_ != JNI_OK && status_ != JNI_EDETACHED) {
881       log::error(
882           "JNIThreadAttacher: unable to get environment for JNI CALL, status: "
883           "{}",
884           status_);
885       env_ = nullptr;
886       return;
887     }
888 
889     if (status_ == JNI_EDETACHED) {
890       char name[17] = {0};
891       if (prctl(PR_GET_NAME, (unsigned long)name) != 0) {
892         log::error(
893             "JNIThreadAttacher: unable to grab previous thread name, error: {}",
894             strerror(errno));
895         env_ = nullptr;
896         return;
897       }
898 
899       JavaVMAttachArgs args = {
900           .version = JNI_VERSION_1_6, .name = name, .group = nullptr};
901       if (vm_->AttachCurrentThread(&env_, &args) != 0) {
902         log::error("JNIThreadAttacher: unable to attach thread to VM");
903         env_ = nullptr;
904         return;
905       }
906     }
907   }
908 
~JNIThreadAttacher()909   ~JNIThreadAttacher() {
910     if (status_ == JNI_EDETACHED) vm_->DetachCurrentThread();
911   }
912 
getEnv()913   JNIEnv* getEnv() { return env_; }
914 
915  private:
916   JavaVM* vm_;
917   JNIEnv* env_;
918   jint status_;
919 };
920 
acquire_wake_lock_callout(const char * lock_name)921 static int acquire_wake_lock_callout(const char* lock_name) {
922   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
923   if (!sJniAdapterServiceObj) {
924     log::error("JNI obj is null. Failed to call JNI callback");
925     return BT_STATUS_NOT_READY;
926   }
927 
928   JNIThreadAttacher attacher(vm);
929   JNIEnv* env = attacher.getEnv();
930 
931   if (env == nullptr) {
932     log::error("Unable to get JNI Env");
933     return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
934   }
935 
936   jint ret = BT_STATUS_SUCCESS;
937   {
938     ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
939     if (lock_name_jni.get()) {
940       bool acquired = env->CallBooleanMethod(
941           sJniCallbacksObj, method_acquireWakeLock, lock_name_jni.get());
942       if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR;
943     } else {
944       log::error("unable to allocate string: {}", lock_name);
945       ret = BT_STATUS_NOMEM;
946     }
947   }
948 
949   return ret;
950 }
951 
release_wake_lock_callout(const char * lock_name)952 static int release_wake_lock_callout(const char* lock_name) {
953   std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
954   if (!sJniAdapterServiceObj) {
955     log::error("JNI obj is null. Failed to call JNI callback");
956     return BT_STATUS_NOT_READY;
957   }
958 
959   JNIThreadAttacher attacher(vm);
960   JNIEnv* env = attacher.getEnv();
961 
962   if (env == nullptr) {
963     log::error("Unable to get JNI Env");
964     return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
965   }
966 
967   jint ret = BT_STATUS_SUCCESS;
968   {
969     ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
970     if (lock_name_jni.get()) {
971       bool released = env->CallBooleanMethod(
972           sJniCallbacksObj, method_releaseWakeLock, lock_name_jni.get());
973       if (!released) ret = BT_STATUS_WAKELOCK_ERROR;
974     } else {
975       log::error("unable to allocate string: {}", lock_name);
976       ret = BT_STATUS_NOMEM;
977     }
978   }
979 
980   return ret;
981 }
982 
983 static bt_os_callouts_t sBluetoothOsCallouts = {
984     sizeof(sBluetoothOsCallouts),
985     acquire_wake_lock_callout,
986     release_wake_lock_callout,
987 };
988 
hal_util_load_bt_library(const bt_interface_t ** interface)989 int hal_util_load_bt_library(const bt_interface_t** interface) {
990   *interface = &bluetoothInterface;
991   return 0;
992 }
993 
initNative(JNIEnv * env,jobject obj,jboolean isGuest,jboolean isCommonCriteriaMode,int configCompareResult,jobjectArray initFlags,jboolean isAtvDevice,jstring userDataDirectory)994 static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest,
995                        jboolean isCommonCriteriaMode, int configCompareResult,
996                        jobjectArray initFlags, jboolean isAtvDevice,
997                        jstring userDataDirectory) {
998   std::unique_lock<std::shared_timed_mutex> lock(jniObjMutex);
999 
1000   log::verbose("");
1001 
1002   android_bluetooth_UidTraffic.clazz =
1003       (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic"));
1004 
1005   sJniAdapterServiceObj = env->NewGlobalRef(obj);
1006   sJniCallbacksObj =
1007       env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
1008 
1009   if (!sBluetoothInterface) {
1010     return JNI_FALSE;
1011   }
1012 
1013   int flagCount = env->GetArrayLength(initFlags);
1014   jstring* flagObjs = new jstring[flagCount];
1015   const char** flags = nullptr;
1016   if (flagCount > 0) {
1017     flags = new const char*[flagCount + 1];
1018     flags[flagCount] = nullptr;
1019   }
1020 
1021   for (int i = 0; i < flagCount; i++) {
1022     flagObjs[i] = (jstring)env->GetObjectArrayElement(initFlags, i);
1023     flags[i] = env->GetStringUTFChars(flagObjs[i], NULL);
1024   }
1025 
1026   const char* user_data_directory =
1027       env->GetStringUTFChars(userDataDirectory, NULL);
1028 
1029   int ret = sBluetoothInterface->init(
1030       &sBluetoothCallbacks, isGuest == JNI_TRUE ? 1 : 0,
1031       isCommonCriteriaMode == JNI_TRUE ? 1 : 0, configCompareResult, flags,
1032       isAtvDevice == JNI_TRUE ? 1 : 0, user_data_directory);
1033 
1034   env->ReleaseStringUTFChars(userDataDirectory, user_data_directory);
1035 
1036   for (int i = 0; i < flagCount; i++) {
1037     env->ReleaseStringUTFChars(flagObjs[i], flags[i]);
1038   }
1039 
1040   delete[] flags;
1041   delete[] flagObjs;
1042 
1043   if (ret != BT_STATUS_SUCCESS) {
1044     log::error("Error while setting the callbacks: {}", ret);
1045     sBluetoothInterface = NULL;
1046     return JNI_FALSE;
1047   }
1048   ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
1049   if (ret != BT_STATUS_SUCCESS) {
1050     log::error("Error while setting Bluetooth callouts: {}", ret);
1051     sBluetoothInterface->cleanup();
1052     sBluetoothInterface = NULL;
1053     return JNI_FALSE;
1054   }
1055 
1056   sBluetoothSocketInterface =
1057       (btsock_interface_t*)sBluetoothInterface->get_profile_interface(
1058           BT_PROFILE_SOCKETS_ID);
1059   if (sBluetoothSocketInterface == NULL) {
1060     log::error("Error getting socket interface");
1061   }
1062 
1063   return JNI_TRUE;
1064 }
1065 
cleanupNative(JNIEnv * env,jobject)1066 static bool cleanupNative(JNIEnv* env, jobject /* obj */) {
1067   std::unique_lock<std::shared_timed_mutex> lock(jniObjMutex);
1068 
1069   log::verbose("");
1070 
1071   if (!sBluetoothInterface) return JNI_FALSE;
1072 
1073   sBluetoothInterface->cleanup();
1074   log::info("return from cleanup");
1075 
1076   if (sJniCallbacksObj) {
1077     env->DeleteGlobalRef(sJniCallbacksObj);
1078     sJniCallbacksObj = NULL;
1079   }
1080 
1081   if (sJniAdapterServiceObj) {
1082     env->DeleteGlobalRef(sJniAdapterServiceObj);
1083     sJniAdapterServiceObj = NULL;
1084   }
1085 
1086   if (android_bluetooth_UidTraffic.clazz) {
1087     env->DeleteGlobalRef(android_bluetooth_UidTraffic.clazz);
1088     android_bluetooth_UidTraffic.clazz = NULL;
1089   }
1090   return JNI_TRUE;
1091 }
1092 
enableNative(JNIEnv *,jobject)1093 static jboolean enableNative(JNIEnv* /* env */, jobject /* obj */) {
1094   log::verbose("");
1095 
1096   if (!sBluetoothInterface) return JNI_FALSE;
1097   int ret = sBluetoothInterface->enable();
1098   return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE
1099                                                              : JNI_FALSE;
1100 }
1101 
disableNative(JNIEnv *,jobject)1102 static jboolean disableNative(JNIEnv* /* env */, jobject /* obj */) {
1103   log::verbose("");
1104 
1105   if (!sBluetoothInterface) return JNI_FALSE;
1106 
1107   int ret = sBluetoothInterface->disable();
1108   /* Retrun JNI_FALSE only when BTIF explicitly reports
1109      BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY
1110      case which indicates that stack had not been enabled.
1111   */
1112   return (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE;
1113 }
1114 
startDiscoveryNative(JNIEnv *,jobject)1115 static jboolean startDiscoveryNative(JNIEnv* /* env */, jobject /* obj */) {
1116   log::verbose("");
1117 
1118   if (!sBluetoothInterface) return JNI_FALSE;
1119 
1120   int ret = sBluetoothInterface->start_discovery();
1121   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1122 }
1123 
cancelDiscoveryNative(JNIEnv *,jobject)1124 static jboolean cancelDiscoveryNative(JNIEnv* /* env */, jobject /* obj */) {
1125   log::verbose("");
1126 
1127   if (!sBluetoothInterface) return JNI_FALSE;
1128 
1129   int ret = sBluetoothInterface->cancel_discovery();
1130   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1131 }
1132 
createBondNative(JNIEnv * env,jobject,jbyteArray address,jint addrType,jint transport)1133 static jboolean createBondNative(JNIEnv* env, jobject /* obj */,
1134                                  jbyteArray address, jint addrType,
1135                                  jint transport) {
1136   log::verbose("");
1137 
1138   if (!sBluetoothInterface) return JNI_FALSE;
1139 
1140   jbyte* addr = env->GetByteArrayElements(address, NULL);
1141   if (addr == NULL) {
1142     jniThrowIOException(env, EINVAL);
1143     return JNI_FALSE;
1144   }
1145 
1146   uint8_t addr_type = (uint8_t)addrType;
1147   int ret = BT_STATUS_SUCCESS;
1148   if (addr_type == BLE_ADDR_RANDOM) {
1149     ret = sBluetoothInterface->create_bond_le((RawAddress*)addr, addr_type);
1150   } else {
1151     ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport);
1152   }
1153 
1154   if (ret != BT_STATUS_SUCCESS) {
1155     log::warn("Failed to initiate bonding. Status = {}", ret);
1156   }
1157 
1158   env->ReleaseByteArrayElements(address, addr, 0);
1159   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1160 }
1161 
callByteArrayGetter(JNIEnv * env,jobject object,const char * className,const char * methodName)1162 static jbyteArray callByteArrayGetter(JNIEnv* env, jobject object,
1163                                       const char* className,
1164                                       const char* methodName) {
1165   jclass myClass = env->FindClass(className);
1166   jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B");
1167   env->DeleteLocalRef(myClass);
1168   return (jbyteArray)env->CallObjectMethod(object, myMethod);
1169 }
1170 
callIntGetter(JNIEnv * env,jobject object,const char * className,const char * methodName)1171 static jint callIntGetter(JNIEnv* env, jobject object, const char* className,
1172                           const char* methodName) {
1173   jclass myClass = env->FindClass(className);
1174   jmethodID myMethod = env->GetMethodID(myClass, methodName, "()I");
1175   env->DeleteLocalRef(myClass);
1176   return env->CallIntMethod(object, myMethod);
1177 }
1178 
set_data(JNIEnv * env,bt_oob_data_t & oob_data,jobject oobData,jint transport)1179 static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData,
1180                          jint transport) {
1181   // Need both arguments to be non NULL
1182   if (oobData == NULL) {
1183     log::error("oobData is null! Nothing to do.");
1184     return JNI_FALSE;
1185   }
1186 
1187   memset(&oob_data, 0, sizeof(oob_data));
1188 
1189   jbyteArray address = callByteArrayGetter(
1190       env, oobData, "android/bluetooth/OobData", "getDeviceAddressWithType");
1191 
1192   // Check the data
1193   int len = env->GetArrayLength(address);
1194   if (len != OOB_ADDRESS_SIZE) {
1195     log::error(
1196         "addressBytes must be 7 bytes in length (address plus type) 6+1!");
1197     jniThrowIOException(env, EINVAL);
1198     return JNI_FALSE;
1199   }
1200 
1201   // Convert the address from byte[]
1202   jbyte* addressBytes = env->GetByteArrayElements(address, NULL);
1203   if (addressBytes == NULL) {
1204     log::error("addressBytes cannot be null!");
1205     jniThrowIOException(env, EINVAL);
1206     return JNI_FALSE;
1207   }
1208   memcpy(oob_data.address, addressBytes, len);
1209 
1210   // Get the device name byte[] java object
1211   jbyteArray deviceName = callByteArrayGetter(
1212       env, oobData, "android/bluetooth/OobData", "getDeviceName");
1213 
1214   // Optional
1215   // Convert it to a jbyte* and copy it to the struct
1216   jbyte* deviceNameBytes = NULL;
1217   if (deviceName != NULL) {
1218     deviceNameBytes = env->GetByteArrayElements(deviceName, NULL);
1219     int len = env->GetArrayLength(deviceName);
1220     if (len > OOB_NAME_MAX_SIZE) {
1221       log::info(
1222           "wrong length of deviceName, should be empty or less than or equal "
1223           "to {} bytes.",
1224           OOB_NAME_MAX_SIZE);
1225       jniThrowIOException(env, EINVAL);
1226       env->ReleaseByteArrayElements(deviceName, deviceNameBytes, 0);
1227       return JNI_FALSE;
1228     }
1229     memcpy(oob_data.device_name, deviceNameBytes, len);
1230     env->ReleaseByteArrayElements(deviceName, deviceNameBytes, 0);
1231   }
1232   // Used by both classic and LE
1233   jbyteArray confirmation = callByteArrayGetter(
1234       env, oobData, "android/bluetooth/OobData", "getConfirmationHash");
1235   if (confirmation == NULL) {
1236     log::error("confirmation cannot be null!");
1237     jniThrowIOException(env, EINVAL);
1238     return JNI_FALSE;
1239   }
1240 
1241   // Confirmation is mandatory
1242   jbyte* confirmationBytes = NULL;
1243   confirmationBytes = env->GetByteArrayElements(confirmation, NULL);
1244   len = env->GetArrayLength(confirmation);
1245   if (confirmationBytes == NULL || len != OOB_C_SIZE) {
1246     log::info("wrong length of Confirmation, should be empty or {} bytes.",
1247               OOB_C_SIZE);
1248     jniThrowIOException(env, EINVAL);
1249     env->ReleaseByteArrayElements(confirmation, confirmationBytes, 0);
1250     return JNI_FALSE;
1251   }
1252   memcpy(oob_data.c, confirmationBytes, len);
1253   env->ReleaseByteArrayElements(confirmation, confirmationBytes, 0);
1254 
1255   // Random is supposedly optional according to the specification
1256   jbyteArray randomizer = callByteArrayGetter(
1257       env, oobData, "android/bluetooth/OobData", "getRandomizerHash");
1258   jbyte* randomizerBytes = NULL;
1259   if (randomizer != NULL) {
1260     randomizerBytes = env->GetByteArrayElements(randomizer, NULL);
1261     int len = env->GetArrayLength(randomizer);
1262     if (randomizerBytes == NULL || len != OOB_R_SIZE) {
1263       log::info("wrong length of Random, should be empty or {} bytes.",
1264                 OOB_R_SIZE);
1265       jniThrowIOException(env, EINVAL);
1266       env->ReleaseByteArrayElements(randomizer, randomizerBytes, 0);
1267       return JNI_FALSE;
1268     }
1269     memcpy(oob_data.r, randomizerBytes, len);
1270     env->ReleaseByteArrayElements(randomizer, randomizerBytes, 0);
1271   }
1272 
1273   // Transport specific data fetching/setting
1274   if (transport == TRANSPORT_BREDR) {
1275     // Classic
1276     // Not optional
1277     jbyteArray oobDataLength = callByteArrayGetter(
1278         env, oobData, "android/bluetooth/OobData", "getClassicLength");
1279     jbyte* oobDataLengthBytes = NULL;
1280     if (oobDataLength == NULL ||
1281         env->GetArrayLength(oobDataLength) != OOB_DATA_LEN_SIZE) {
1282       log::info("wrong length of oobDataLength, should be empty or {} bytes.",
1283                 OOB_DATA_LEN_SIZE);
1284       jniThrowIOException(env, EINVAL);
1285       env->ReleaseByteArrayElements(oobDataLength, oobDataLengthBytes, 0);
1286       return JNI_FALSE;
1287     }
1288 
1289     oobDataLengthBytes = env->GetByteArrayElements(oobDataLength, NULL);
1290     memcpy(oob_data.oob_data_length, oobDataLengthBytes, OOB_DATA_LEN_SIZE);
1291     env->ReleaseByteArrayElements(oobDataLength, oobDataLengthBytes, 0);
1292 
1293     // Optional
1294     jbyteArray classOfDevice = callByteArrayGetter(
1295         env, oobData, "android/bluetooth/OobData", "getClassOfDevice");
1296     jbyte* classOfDeviceBytes = NULL;
1297     if (classOfDevice != NULL) {
1298       classOfDeviceBytes = env->GetByteArrayElements(classOfDevice, NULL);
1299       int len = env->GetArrayLength(classOfDevice);
1300       if (len != OOB_COD_SIZE) {
1301         log::info("wrong length of classOfDevice, should be empty or {} bytes.",
1302                   OOB_COD_SIZE);
1303         jniThrowIOException(env, EINVAL);
1304         env->ReleaseByteArrayElements(classOfDevice, classOfDeviceBytes, 0);
1305         return JNI_FALSE;
1306       }
1307       memcpy(oob_data.class_of_device, classOfDeviceBytes, len);
1308       env->ReleaseByteArrayElements(classOfDevice, classOfDeviceBytes, 0);
1309     }
1310   } else if (transport == TRANSPORT_LE) {
1311     // LE
1312     jbyteArray temporaryKey = callByteArrayGetter(
1313         env, oobData, "android/bluetooth/OobData", "getLeTemporaryKey");
1314     jbyte* temporaryKeyBytes = NULL;
1315     if (temporaryKey != NULL) {
1316       temporaryKeyBytes = env->GetByteArrayElements(temporaryKey, NULL);
1317       int len = env->GetArrayLength(temporaryKey);
1318       if (len != OOB_TK_SIZE) {
1319         log::info("wrong length of temporaryKey, should be empty or {} bytes.",
1320                   OOB_TK_SIZE);
1321         jniThrowIOException(env, EINVAL);
1322         env->ReleaseByteArrayElements(temporaryKey, temporaryKeyBytes, 0);
1323         return JNI_FALSE;
1324       }
1325       memcpy(oob_data.sm_tk, temporaryKeyBytes, len);
1326       env->ReleaseByteArrayElements(temporaryKey, temporaryKeyBytes, 0);
1327     }
1328 
1329     jbyteArray leAppearance = callByteArrayGetter(
1330         env, oobData, "android/bluetooth/OobData", "getLeAppearance");
1331     jbyte* leAppearanceBytes = NULL;
1332     if (leAppearance != NULL) {
1333       leAppearanceBytes = env->GetByteArrayElements(leAppearance, NULL);
1334       int len = env->GetArrayLength(leAppearance);
1335       if (len != OOB_LE_APPEARANCE_SIZE) {
1336         log::info("wrong length of leAppearance, should be empty or {} bytes.",
1337                   OOB_LE_APPEARANCE_SIZE);
1338         jniThrowIOException(env, EINVAL);
1339         env->ReleaseByteArrayElements(leAppearance, leAppearanceBytes, 0);
1340         return JNI_FALSE;
1341       }
1342       memcpy(oob_data.le_appearance, leAppearanceBytes, len);
1343       env->ReleaseByteArrayElements(leAppearance, leAppearanceBytes, 0);
1344     }
1345 
1346     jint leRole = callIntGetter(env, oobData, "android/bluetooth/OobData",
1347                                 "getLeDeviceRole");
1348     oob_data.le_device_role = leRole;
1349 
1350     jint leFlag =
1351         callIntGetter(env, oobData, "android/bluetooth/OobData", "getLeFlags");
1352     oob_data.le_flags = leFlag;
1353   }
1354   return JNI_TRUE;
1355 }
1356 
generateLocalOobDataNative(JNIEnv *,jobject,jint transport)1357 static void generateLocalOobDataNative(JNIEnv* /* env */, jobject /* obj */,
1358                                        jint transport) {
1359   // No BT interface? Can't do anything.
1360   if (!sBluetoothInterface) return;
1361 
1362   if (sBluetoothInterface->generate_local_oob_data(transport) !=
1363       BT_STATUS_SUCCESS) {
1364     log::error("Call to generate_local_oob_data failed!");
1365     bt_oob_data_t oob_data;
1366     oob_data.is_valid = false;
1367     generate_local_oob_data_callback(transport, oob_data);
1368   }
1369 }
1370 
createBondOutOfBandNative(JNIEnv * env,jobject,jbyteArray address,jint transport,jobject p192Data,jobject p256Data)1371 static jboolean createBondOutOfBandNative(JNIEnv* env, jobject /* obj */,
1372                                           jbyteArray address, jint transport,
1373                                           jobject p192Data, jobject p256Data) {
1374   // No BT interface? Can't do anything.
1375   if (!sBluetoothInterface) return JNI_FALSE;
1376 
1377   // No data? Can't do anything
1378   if (p192Data == NULL && p256Data == NULL) {
1379     log::error("All OOB Data are null! Nothing to do.");
1380     jniThrowIOException(env, EINVAL);
1381     return JNI_FALSE;
1382   }
1383 
1384   // This address is already reversed which is why its being passed...
1385   // In the future we want to remove this and just reverse the address
1386   // for the oobdata in the host stack.
1387   if (address == NULL) {
1388     log::error("Address cannot be null! Nothing to do.");
1389     jniThrowIOException(env, EINVAL);
1390     return JNI_FALSE;
1391   }
1392 
1393   // Check the data
1394   int len = env->GetArrayLength(address);
1395   if (len != 6) {
1396     log::error(
1397         "addressBytes must be 6 bytes in length (address plus type) 6+1!");
1398     jniThrowIOException(env, EINVAL);
1399     return JNI_FALSE;
1400   }
1401 
1402   jbyte* addr = env->GetByteArrayElements(address, NULL);
1403   if (addr == NULL) {
1404     jniThrowIOException(env, EINVAL);
1405     return JNI_FALSE;
1406   }
1407 
1408   // Convert P192 data from Java POJO to C Struct
1409   bt_oob_data_t p192_data;
1410   if (p192Data != NULL) {
1411     if (set_data(env, p192_data, p192Data, transport) == JNI_FALSE) {
1412       jniThrowIOException(env, EINVAL);
1413       return JNI_FALSE;
1414     }
1415   }
1416 
1417   // Convert P256 data from Java POJO to C Struct
1418   bt_oob_data_t p256_data;
1419   if (p256Data != NULL) {
1420     if (set_data(env, p256_data, p256Data, transport) == JNI_FALSE) {
1421       jniThrowIOException(env, EINVAL);
1422       return JNI_FALSE;
1423     }
1424   }
1425 
1426   return ((sBluetoothInterface->create_bond_out_of_band(
1427               (RawAddress*)addr, transport, &p192_data, &p256_data)) ==
1428           BT_STATUS_SUCCESS)
1429              ? JNI_TRUE
1430              : JNI_FALSE;
1431 }
1432 
removeBondNative(JNIEnv * env,jobject,jbyteArray address)1433 static jboolean removeBondNative(JNIEnv* env, jobject /* obj */,
1434                                  jbyteArray address) {
1435   log::verbose("");
1436 
1437   if (!sBluetoothInterface) return JNI_FALSE;
1438 
1439   jbyte* addr = env->GetByteArrayElements(address, NULL);
1440   if (addr == NULL) {
1441     jniThrowIOException(env, EINVAL);
1442     return JNI_FALSE;
1443   }
1444 
1445   int ret = sBluetoothInterface->remove_bond((RawAddress*)addr);
1446   env->ReleaseByteArrayElements(address, addr, 0);
1447 
1448   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1449 }
1450 
cancelBondNative(JNIEnv * env,jobject,jbyteArray address)1451 static jboolean cancelBondNative(JNIEnv* env, jobject /* obj */,
1452                                  jbyteArray address) {
1453   log::verbose("");
1454 
1455   if (!sBluetoothInterface) return JNI_FALSE;
1456 
1457   jbyte* addr = env->GetByteArrayElements(address, NULL);
1458   if (addr == NULL) {
1459     jniThrowIOException(env, EINVAL);
1460     return JNI_FALSE;
1461   }
1462 
1463   int ret = sBluetoothInterface->cancel_bond((RawAddress*)addr);
1464   env->ReleaseByteArrayElements(address, addr, 0);
1465   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1466 }
1467 
pairingIsBusyNative(JNIEnv *,jobject)1468 static jboolean pairingIsBusyNative(JNIEnv* /*env*/, jobject /* obj */) {
1469   log::verbose("");
1470 
1471   if (!sBluetoothInterface) return JNI_FALSE;
1472 
1473   return sBluetoothInterface->pairing_is_busy();
1474 }
1475 
getConnectionStateNative(JNIEnv * env,jobject,jbyteArray address)1476 static int getConnectionStateNative(JNIEnv* env, jobject /* obj */,
1477                                     jbyteArray address) {
1478   log::verbose("");
1479   if (!sBluetoothInterface) return JNI_FALSE;
1480 
1481   jbyte* addr = env->GetByteArrayElements(address, NULL);
1482   if (addr == NULL) {
1483     jniThrowIOException(env, EINVAL);
1484     return JNI_FALSE;
1485   }
1486 
1487   int ret = sBluetoothInterface->get_connection_state((RawAddress*)addr);
1488   env->ReleaseByteArrayElements(address, addr, 0);
1489 
1490   return ret;
1491 }
1492 
pinReplyNative(JNIEnv * env,jobject,jbyteArray address,jboolean accept,jint len,jbyteArray pinArray)1493 static jboolean pinReplyNative(JNIEnv* env, jobject /* obj */,
1494                                jbyteArray address, jboolean accept, jint len,
1495                                jbyteArray pinArray) {
1496   log::verbose("");
1497 
1498   if (!sBluetoothInterface) return JNI_FALSE;
1499 
1500   jbyte* addr = env->GetByteArrayElements(address, NULL);
1501   if (addr == NULL) {
1502     jniThrowIOException(env, EINVAL);
1503     return JNI_FALSE;
1504   }
1505 
1506   jbyte* pinPtr = NULL;
1507   if (accept) {
1508     pinPtr = env->GetByteArrayElements(pinArray, NULL);
1509     if (pinPtr == NULL) {
1510       jniThrowIOException(env, EINVAL);
1511       env->ReleaseByteArrayElements(address, addr, 0);
1512       return JNI_FALSE;
1513     }
1514   }
1515 
1516   int ret = sBluetoothInterface->pin_reply((RawAddress*)addr, accept, len,
1517                                            (bt_pin_code_t*)pinPtr);
1518   env->ReleaseByteArrayElements(address, addr, 0);
1519   env->ReleaseByteArrayElements(pinArray, pinPtr, 0);
1520 
1521   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1522 }
1523 
sspReplyNative(JNIEnv * env,jobject,jbyteArray address,jint type,jboolean accept,jint passkey)1524 static jboolean sspReplyNative(JNIEnv* env, jobject /* obj */,
1525                                jbyteArray address, jint type, jboolean accept,
1526                                jint passkey) {
1527   log::verbose("");
1528 
1529   if (!sBluetoothInterface) return JNI_FALSE;
1530 
1531   jbyte* addr = env->GetByteArrayElements(address, NULL);
1532   if (addr == NULL) {
1533     jniThrowIOException(env, EINVAL);
1534     return JNI_FALSE;
1535   }
1536 
1537   int ret = sBluetoothInterface->ssp_reply(
1538       (RawAddress*)addr, (bt_ssp_variant_t)type, accept, passkey);
1539   env->ReleaseByteArrayElements(address, addr, 0);
1540 
1541   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1542 }
1543 
setAdapterPropertyNative(JNIEnv * env,jobject,jint type,jbyteArray value)1544 static jboolean setAdapterPropertyNative(JNIEnv* env, jobject /* obj */,
1545                                          jint type, jbyteArray value) {
1546   log::verbose("");
1547 
1548   if (!sBluetoothInterface) return JNI_FALSE;
1549 
1550   jbyte* val = env->GetByteArrayElements(value, NULL);
1551   bt_property_t prop;
1552   prop.type = (bt_property_type_t)type;
1553   prop.len = env->GetArrayLength(value);
1554   prop.val = val;
1555 
1556   int ret = sBluetoothInterface->set_adapter_property(&prop);
1557   env->ReleaseByteArrayElements(value, val, 0);
1558 
1559   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1560 }
1561 
getAdapterPropertiesNative(JNIEnv *,jobject)1562 static jboolean getAdapterPropertiesNative(JNIEnv* /* env */,
1563                                            jobject /* obj */) {
1564   log::verbose("");
1565 
1566   if (!sBluetoothInterface) return JNI_FALSE;
1567 
1568   int ret = sBluetoothInterface->get_adapter_properties();
1569   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1570 }
1571 
getAdapterPropertyNative(JNIEnv *,jobject,jint type)1572 static jboolean getAdapterPropertyNative(JNIEnv* /* env */, jobject /* obj */,
1573                                          jint type) {
1574   log::verbose("");
1575 
1576   if (!sBluetoothInterface) return JNI_FALSE;
1577 
1578   int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t)type);
1579   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1580 }
1581 
getDevicePropertyNative(JNIEnv * env,jobject,jbyteArray address,jint type)1582 static jboolean getDevicePropertyNative(JNIEnv* env, jobject /* obj */,
1583                                         jbyteArray address, jint type) {
1584   log::verbose("");
1585 
1586   if (!sBluetoothInterface) return JNI_FALSE;
1587 
1588   jbyte* addr = env->GetByteArrayElements(address, NULL);
1589   if (addr == NULL) {
1590     jniThrowIOException(env, EINVAL);
1591     return JNI_FALSE;
1592   }
1593 
1594   int ret = sBluetoothInterface->get_remote_device_property(
1595       (RawAddress*)addr, (bt_property_type_t)type);
1596   env->ReleaseByteArrayElements(address, addr, 0);
1597   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1598 }
1599 
setDevicePropertyNative(JNIEnv * env,jobject,jbyteArray address,jint type,jbyteArray value)1600 static jboolean setDevicePropertyNative(JNIEnv* env, jobject /* obj */,
1601                                         jbyteArray address, jint type,
1602                                         jbyteArray value) {
1603   log::verbose("");
1604 
1605   if (!sBluetoothInterface) return JNI_FALSE;
1606 
1607   jbyte* val = env->GetByteArrayElements(value, NULL);
1608   if (val == NULL) {
1609     jniThrowIOException(env, EINVAL);
1610     return JNI_FALSE;
1611   }
1612 
1613   jbyte* addr = env->GetByteArrayElements(address, NULL);
1614   if (addr == NULL) {
1615     env->ReleaseByteArrayElements(value, val, 0);
1616     jniThrowIOException(env, EINVAL);
1617     return JNI_FALSE;
1618   }
1619 
1620   bt_property_t prop;
1621   prop.type = (bt_property_type_t)type;
1622   prop.len = env->GetArrayLength(value);
1623   prop.val = val;
1624 
1625   int ret =
1626       sBluetoothInterface->set_remote_device_property((RawAddress*)addr, &prop);
1627   env->ReleaseByteArrayElements(value, val, 0);
1628   env->ReleaseByteArrayElements(address, addr, 0);
1629 
1630   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1631 }
1632 
getRemoteServicesNative(JNIEnv * env,jobject,jbyteArray address,jint transport)1633 static jboolean getRemoteServicesNative(JNIEnv* env, jobject /* obj */,
1634                                         jbyteArray address, jint transport) {
1635   log::verbose("");
1636 
1637   if (!sBluetoothInterface) return JNI_FALSE;
1638 
1639   jbyte* addr = addr = env->GetByteArrayElements(address, NULL);
1640   if (addr == NULL) {
1641     jniThrowIOException(env, EINVAL);
1642     return JNI_FALSE;
1643   }
1644 
1645   int ret =
1646       sBluetoothInterface->get_remote_services((RawAddress*)addr, transport);
1647   env->ReleaseByteArrayElements(address, addr, 0);
1648   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1649 }
1650 
readEnergyInfoNative()1651 static int readEnergyInfoNative() {
1652   log::verbose("");
1653 
1654   if (!sBluetoothInterface) return JNI_FALSE;
1655   int ret = sBluetoothInterface->read_energy_info();
1656   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1657 }
1658 
dumpNative(JNIEnv * env,jobject,jobject fdObj,jobjectArray argArray)1659 static void dumpNative(JNIEnv* env, jobject /* obj */, jobject fdObj,
1660                        jobjectArray argArray) {
1661   log::verbose("");
1662   if (!sBluetoothInterface) return;
1663 
1664   int fd = jniGetFDFromFileDescriptor(env, fdObj);
1665   if (fd < 0) return;
1666 
1667   int numArgs = env->GetArrayLength(argArray);
1668 
1669   jstring* argObjs = new jstring[numArgs];
1670   const char** args = nullptr;
1671   if (numArgs > 0) {
1672     args = new const char*[numArgs + 1];
1673     args[numArgs] = nullptr;
1674   }
1675 
1676   for (int i = 0; i < numArgs; i++) {
1677     argObjs[i] = (jstring)env->GetObjectArrayElement(argArray, i);
1678     args[i] = env->GetStringUTFChars(argObjs[i], NULL);
1679   }
1680 
1681   sBluetoothInterface->dump(fd, args);
1682 
1683   for (int i = 0; i < numArgs; i++) {
1684     env->ReleaseStringUTFChars(argObjs[i], args[i]);
1685   }
1686 
1687   delete[] args;
1688   delete[] argObjs;
1689 }
1690 
dumpMetricsNative(JNIEnv * env,jobject)1691 static jbyteArray dumpMetricsNative(JNIEnv* env, jobject /* obj */) {
1692   log::info("");
1693   if (!sBluetoothInterface) return env->NewByteArray(0);
1694 
1695   std::string output;
1696   sBluetoothInterface->dumpMetrics(&output);
1697   jsize output_size = output.size() * sizeof(char);
1698   jbyteArray output_bytes = env->NewByteArray(output_size);
1699   env->SetByteArrayRegion(output_bytes, 0, output_size,
1700                           (const jbyte*)output.data());
1701   return output_bytes;
1702 }
1703 
factoryResetNative(JNIEnv *,jobject)1704 static jboolean factoryResetNative(JNIEnv* /* env */, jobject /* obj */) {
1705   log::verbose("");
1706   if (!sBluetoothInterface) return JNI_FALSE;
1707   int ret = sBluetoothInterface->config_clear();
1708   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1709 }
1710 
obfuscateAddressNative(JNIEnv * env,jobject,jbyteArray address)1711 static jbyteArray obfuscateAddressNative(JNIEnv* env, jobject /* obj */,
1712                                          jbyteArray address) {
1713   log::verbose("");
1714   if (!sBluetoothInterface) return env->NewByteArray(0);
1715   jbyte* addr = env->GetByteArrayElements(address, nullptr);
1716   if (addr == nullptr) {
1717     jniThrowIOException(env, EINVAL);
1718     return env->NewByteArray(0);
1719   }
1720   RawAddress addr_obj = {};
1721   addr_obj.FromOctets((uint8_t*)addr);
1722   std::string output = sBluetoothInterface->obfuscate_address(addr_obj);
1723   jsize output_size = output.size() * sizeof(char);
1724   jbyteArray output_bytes = env->NewByteArray(output_size);
1725   env->SetByteArrayRegion(output_bytes, 0, output_size,
1726                           (const jbyte*)output.data());
1727   return output_bytes;
1728 }
1729 
setBufferLengthMillisNative(JNIEnv *,jobject,jint codec,jint size)1730 static jboolean setBufferLengthMillisNative(JNIEnv* /* env */,
1731                                             jobject /* obj */, jint codec,
1732                                             jint size) {
1733   log::verbose("");
1734 
1735   if (!sBluetoothInterface) return JNI_FALSE;
1736 
1737   int ret = sBluetoothInterface->set_dynamic_audio_buffer_size(codec, size);
1738   return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1739 }
1740 
connectSocketNative(JNIEnv * env,jobject,jbyteArray address,jint type,jbyteArray uuid,jint port,jint flag,jint callingUid)1741 static jint connectSocketNative(JNIEnv* env, jobject /* obj */,
1742                                 jbyteArray address, jint type, jbyteArray uuid,
1743                                 jint port, jint flag, jint callingUid) {
1744   int socket_fd = INVALID_FD;
1745   jbyte* addr = nullptr;
1746   jbyte* uuidBytes = nullptr;
1747   Uuid btUuid;
1748 
1749   if (!sBluetoothSocketInterface) {
1750     goto done;
1751   }
1752   addr = env->GetByteArrayElements(address, nullptr);
1753   uuidBytes = env->GetByteArrayElements(uuid, nullptr);
1754   if (addr == nullptr || uuidBytes == nullptr) {
1755     jniThrowIOException(env, EINVAL);
1756     goto done;
1757   }
1758 
1759   btUuid = Uuid::From128BitBE((uint8_t*)uuidBytes);
1760   if (sBluetoothSocketInterface->connect((RawAddress*)addr, (btsock_type_t)type,
1761                                          &btUuid, port, &socket_fd, flag,
1762                                          callingUid) != BT_STATUS_SUCCESS) {
1763     socket_fd = INVALID_FD;
1764   }
1765 
1766 done:
1767   if (addr) env->ReleaseByteArrayElements(address, addr, 0);
1768   if (uuidBytes) env->ReleaseByteArrayElements(uuid, uuidBytes, 0);
1769   return socket_fd;
1770 }
1771 
createSocketChannelNative(JNIEnv * env,jobject,jint type,jstring serviceName,jbyteArray uuid,jint port,jint flag,jint callingUid)1772 static jint createSocketChannelNative(JNIEnv* env, jobject /* obj */, jint type,
1773                                       jstring serviceName, jbyteArray uuid,
1774                                       jint port, jint flag, jint callingUid) {
1775   int socket_fd = INVALID_FD;
1776   jbyte* uuidBytes = nullptr;
1777   Uuid btUuid;
1778   const char* nativeServiceName = nullptr;
1779 
1780   if (!sBluetoothSocketInterface) {
1781     goto done;
1782   }
1783   uuidBytes = env->GetByteArrayElements(uuid, nullptr);
1784   if (serviceName != nullptr) {
1785     nativeServiceName = env->GetStringUTFChars(serviceName, nullptr);
1786   }
1787   if (uuidBytes == nullptr) {
1788     jniThrowIOException(env, EINVAL);
1789     goto done;
1790   }
1791   btUuid = Uuid::From128BitBE((uint8_t*)uuidBytes);
1792 
1793   if (sBluetoothSocketInterface->listen((btsock_type_t)type, nativeServiceName,
1794                                         &btUuid, port, &socket_fd, flag,
1795                                         callingUid) != BT_STATUS_SUCCESS) {
1796     socket_fd = INVALID_FD;
1797   }
1798 
1799 done:
1800   if (uuidBytes) env->ReleaseByteArrayElements(uuid, uuidBytes, 0);
1801   if (nativeServiceName)
1802     env->ReleaseStringUTFChars(serviceName, nativeServiceName);
1803   return socket_fd;
1804 }
1805 
requestMaximumTxDataLengthNative(JNIEnv * env,jobject,jbyteArray address)1806 static void requestMaximumTxDataLengthNative(JNIEnv* env, jobject /* obj */,
1807                                              jbyteArray address) {
1808   if (!sBluetoothSocketInterface) {
1809     return;
1810   }
1811   jbyte* addr = env->GetByteArrayElements(address, nullptr);
1812   if (addr == nullptr) {
1813     jniThrowIOException(env, EINVAL);
1814     return;
1815   }
1816 
1817   RawAddress addressVar = *(RawAddress*)addr;
1818   sBluetoothSocketInterface->request_max_tx_data_length(addressVar);
1819   env->ReleaseByteArrayElements(address, addr, 1);
1820 }
1821 
getMetricIdNative(JNIEnv * env,jobject,jbyteArray address)1822 static int getMetricIdNative(JNIEnv* env, jobject /* obj */,
1823                              jbyteArray address) {
1824   log::verbose("");
1825   if (!sBluetoothInterface) return 0;  // 0 is invalid id
1826   jbyte* addr = env->GetByteArrayElements(address, nullptr);
1827   if (addr == nullptr) {
1828     jniThrowIOException(env, EINVAL);
1829     return 0;
1830   }
1831   RawAddress addr_obj = {};
1832   addr_obj.FromOctets((uint8_t*)addr);
1833   return sBluetoothInterface->get_metric_id(addr_obj);
1834 }
1835 
allowLowLatencyAudioNative(JNIEnv * env,jobject,jboolean allowed,jbyteArray address)1836 static jboolean allowLowLatencyAudioNative(JNIEnv* env, jobject /* obj */,
1837                                            jboolean allowed,
1838                                            jbyteArray address) {
1839   log::verbose("");
1840   if (!sBluetoothInterface) return false;
1841   jbyte* addr = env->GetByteArrayElements(address, nullptr);
1842   if (addr == nullptr) {
1843     jniThrowIOException(env, EINVAL);
1844     return false;
1845   }
1846 
1847   RawAddress addr_obj = {};
1848   addr_obj.FromOctets((uint8_t*)addr);
1849   sBluetoothInterface->allow_low_latency_audio(allowed, addr_obj);
1850   return true;
1851 }
1852 
metadataChangedNative(JNIEnv * env,jobject,jbyteArray address,jint key,jbyteArray value)1853 static void metadataChangedNative(JNIEnv* env, jobject /* obj */,
1854                                   jbyteArray address, jint key,
1855                                   jbyteArray value) {
1856   log::verbose("");
1857   if (!sBluetoothInterface) return;
1858   jbyte* addr = env->GetByteArrayElements(address, nullptr);
1859   if (addr == nullptr) {
1860     jniThrowIOException(env, EINVAL);
1861     return;
1862   }
1863   RawAddress addr_obj = {};
1864   addr_obj.FromOctets((uint8_t*)addr);
1865 
1866   if (value == NULL) {
1867     log::error("metadataChangedNative() ignoring NULL array");
1868     return;
1869   }
1870 
1871   uint16_t len = (uint16_t)env->GetArrayLength(value);
1872   jbyte* p_value = env->GetByteArrayElements(value, NULL);
1873   if (p_value == NULL) return;
1874 
1875   std::vector<uint8_t> val_vec(reinterpret_cast<uint8_t*>(p_value),
1876                                reinterpret_cast<uint8_t*>(p_value + len));
1877   env->ReleaseByteArrayElements(value, p_value, 0);
1878 
1879   sBluetoothInterface->metadata_changed(addr_obj, key, std::move(val_vec));
1880   return;
1881 }
1882 
isLogRedactionEnabledNative(JNIEnv *,jobject)1883 static jboolean isLogRedactionEnabledNative(JNIEnv* /* env */,
1884                                             jobject /* obj */) {
1885   log::verbose("");
1886   return bluetooth::os::should_log_be_redacted();
1887 }
1888 
interopMatchAddrNative(JNIEnv * env,jclass,jstring feature_name,jstring address)1889 static jboolean interopMatchAddrNative(JNIEnv* env, jclass /* clazz */,
1890                                        jstring feature_name, jstring address) {
1891   log::verbose("");
1892 
1893   if (!sBluetoothInterface) {
1894     log::warn("sBluetoothInterface is null.");
1895     return JNI_FALSE;
1896   }
1897 
1898   const char* tmp_addr = env->GetStringUTFChars(address, NULL);
1899   if (!tmp_addr) {
1900     log::warn("address is null.");
1901     return JNI_FALSE;
1902   }
1903   RawAddress bdaddr;
1904   bool success = RawAddress::FromString(tmp_addr, bdaddr);
1905 
1906   env->ReleaseStringUTFChars(address, tmp_addr);
1907 
1908   if (!success) {
1909     log::warn("address is invalid.");
1910     return JNI_FALSE;
1911   }
1912 
1913   const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
1914   if (!feature_name_str) {
1915     log::warn("feature name is null.");
1916     return JNI_FALSE;
1917   }
1918 
1919   bool matched =
1920       sBluetoothInterface->interop_match_addr(feature_name_str, &bdaddr);
1921   env->ReleaseStringUTFChars(feature_name, feature_name_str);
1922 
1923   return matched ? JNI_TRUE : JNI_FALSE;
1924 }
1925 
interopMatchNameNative(JNIEnv * env,jclass,jstring feature_name,jstring name)1926 static jboolean interopMatchNameNative(JNIEnv* env, jclass /* clazz */,
1927                                        jstring feature_name, jstring name) {
1928   log::verbose("");
1929 
1930   if (!sBluetoothInterface) {
1931     log::warn("sBluetoothInterface is null.");
1932     return JNI_FALSE;
1933   }
1934 
1935   const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
1936   if (!feature_name_str) {
1937     log::warn("feature name is null.");
1938     return JNI_FALSE;
1939   }
1940 
1941   const char* name_str = env->GetStringUTFChars(name, NULL);
1942   if (!name_str) {
1943     log::warn("name is null.");
1944     env->ReleaseStringUTFChars(feature_name, feature_name_str);
1945     return JNI_FALSE;
1946   }
1947 
1948   bool matched =
1949       sBluetoothInterface->interop_match_name(feature_name_str, name_str);
1950   env->ReleaseStringUTFChars(feature_name, feature_name_str);
1951   env->ReleaseStringUTFChars(name, name_str);
1952 
1953   return matched ? JNI_TRUE : JNI_FALSE;
1954 }
1955 
interopMatchAddrOrNameNative(JNIEnv * env,jclass,jstring feature_name,jstring address)1956 static jboolean interopMatchAddrOrNameNative(JNIEnv* env, jclass /* clazz */,
1957                                              jstring feature_name,
1958                                              jstring address) {
1959   log::verbose("");
1960 
1961   if (!sBluetoothInterface) {
1962     log::warn("sBluetoothInterface is null.");
1963     return JNI_FALSE;
1964   }
1965 
1966   const char* tmp_addr = env->GetStringUTFChars(address, NULL);
1967   if (!tmp_addr) {
1968     log::warn("address is null.");
1969     return JNI_FALSE;
1970   }
1971   RawAddress bdaddr;
1972   bool success = RawAddress::FromString(tmp_addr, bdaddr);
1973 
1974   env->ReleaseStringUTFChars(address, tmp_addr);
1975 
1976   if (!success) {
1977     log::warn("address is invalid.");
1978     return JNI_FALSE;
1979   }
1980 
1981   const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
1982   if (!feature_name_str) {
1983     log::warn("feature name is null.");
1984     return JNI_FALSE;
1985   }
1986 
1987   bool matched = sBluetoothInterface->interop_match_addr_or_name(
1988       feature_name_str, &bdaddr);
1989   env->ReleaseStringUTFChars(feature_name, feature_name_str);
1990 
1991   return matched ? JNI_TRUE : JNI_FALSE;
1992 }
1993 
interopDatabaseAddRemoveAddrNative(JNIEnv * env,jclass,jboolean do_add,jstring feature_name,jstring address,jint length)1994 static void interopDatabaseAddRemoveAddrNative(JNIEnv* env, jclass /* clazz */,
1995                                                jboolean do_add,
1996                                                jstring feature_name,
1997                                                jstring address, jint length) {
1998   log::verbose("");
1999 
2000   if (!sBluetoothInterface) {
2001     log::warn("sBluetoothInterface is null.");
2002     return;
2003   }
2004 
2005   if ((do_add == JNI_TRUE) && (length <= 0 || length > 6)) {
2006     log::error("address length {} is invalid, valid length is [1,6]", length);
2007     return;
2008   }
2009 
2010   const char* tmp_addr = env->GetStringUTFChars(address, NULL);
2011   if (!tmp_addr) {
2012     log::warn("address is null.");
2013     return;
2014   }
2015   RawAddress bdaddr;
2016   bool success = RawAddress::FromString(tmp_addr, bdaddr);
2017 
2018   env->ReleaseStringUTFChars(address, tmp_addr);
2019 
2020   if (!success) {
2021     log::warn("address is invalid.");
2022     return;
2023   }
2024 
2025   const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
2026   if (!feature_name_str) {
2027     log::warn("feature name is null.");
2028     return;
2029   }
2030 
2031   sBluetoothInterface->interop_database_add_remove_addr(
2032       (do_add == JNI_TRUE), feature_name_str, &bdaddr, (int)length);
2033 
2034   env->ReleaseStringUTFChars(feature_name, feature_name_str);
2035 }
2036 
interopDatabaseAddRemoveNameNative(JNIEnv * env,jclass,jboolean do_add,jstring feature_name,jstring name)2037 static void interopDatabaseAddRemoveNameNative(JNIEnv* env, jclass /* clazz */,
2038                                                jboolean do_add,
2039                                                jstring feature_name,
2040                                                jstring name) {
2041   log::verbose("");
2042 
2043   if (!sBluetoothInterface) {
2044     log::warn("sBluetoothInterface is null.");
2045     return;
2046   }
2047 
2048   const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
2049   if (!feature_name_str) {
2050     log::warn("feature name is null.");
2051     return;
2052   }
2053 
2054   const char* name_str = env->GetStringUTFChars(name, NULL);
2055   if (!name_str) {
2056     log::warn("name is null.");
2057     env->ReleaseStringUTFChars(feature_name, feature_name_str);
2058     return;
2059   }
2060 
2061   sBluetoothInterface->interop_database_add_remove_name(
2062       (do_add == JNI_TRUE), feature_name_str, name_str);
2063 
2064   env->ReleaseStringUTFChars(feature_name, feature_name_str);
2065   env->ReleaseStringUTFChars(name, name_str);
2066 }
2067 
getRemotePbapPceVersionNative(JNIEnv * env,jobject,jstring address)2068 static int getRemotePbapPceVersionNative(JNIEnv* env, jobject /* obj */,
2069                                          jstring address) {
2070   log::verbose("");
2071 
2072   if (!sBluetoothInterface) return JNI_FALSE;
2073 
2074   const char* tmp_addr = env->GetStringUTFChars(address, NULL);
2075   if (!tmp_addr) {
2076     log::warn("address is null.");
2077     return JNI_FALSE;
2078   }
2079 
2080   RawAddress bdaddr;
2081   bool success = RawAddress::FromString(tmp_addr, bdaddr);
2082 
2083   env->ReleaseStringUTFChars(address, tmp_addr);
2084 
2085   if (!success) {
2086     log::warn("address is invalid.");
2087     return JNI_FALSE;
2088   }
2089 
2090   return sBluetoothInterface->get_remote_pbap_pce_version(&bdaddr);
2091 }
2092 
pbapPseDynamicVersionUpgradeIsEnabledNative(JNIEnv *,jobject)2093 static jboolean pbapPseDynamicVersionUpgradeIsEnabledNative(JNIEnv* /* env */,
2094                                                             jobject /* obj */) {
2095   log::verbose("");
2096 
2097   if (!sBluetoothInterface) return JNI_FALSE;
2098 
2099   return sBluetoothInterface->pbap_pse_dynamic_version_upgrade_is_enabled()
2100              ? JNI_TRUE
2101              : JNI_FALSE;
2102 }
2103 
getSocketL2capLocalChannelIdNative(JNIEnv *,jobject,jlong conn_uuid_lsb,jlong conn_uuid_msb)2104 static jint getSocketL2capLocalChannelIdNative(JNIEnv* /* env */,
2105                                                jobject /* obj */,
2106                                                jlong conn_uuid_lsb,
2107                                                jlong conn_uuid_msb) {
2108   log::verbose("");
2109 
2110   if (!sBluetoothSocketInterface) {
2111     return INVALID_CID;
2112   }
2113   uint16_t cid;
2114   Uuid uuid = from_java_uuid(conn_uuid_msb, conn_uuid_lsb);
2115   if (sBluetoothSocketInterface->get_l2cap_local_cid(uuid, &cid) !=
2116       BT_STATUS_SUCCESS) {
2117     return INVALID_CID;
2118   }
2119   return (jint)cid;
2120 }
2121 
getSocketL2capRemoteChannelIdNative(JNIEnv *,jobject,jlong conn_uuid_lsb,jlong conn_uuid_msb)2122 static jint getSocketL2capRemoteChannelIdNative(JNIEnv* /* env */,
2123                                                 jobject /* obj */,
2124                                                 jlong conn_uuid_lsb,
2125                                                 jlong conn_uuid_msb) {
2126   log::verbose("");
2127 
2128   if (!sBluetoothSocketInterface) {
2129     return INVALID_CID;
2130   }
2131   uint16_t cid;
2132   Uuid uuid = from_java_uuid(conn_uuid_msb, conn_uuid_lsb);
2133   if (sBluetoothSocketInterface->get_l2cap_remote_cid(uuid, &cid) !=
2134       BT_STATUS_SUCCESS) {
2135     return INVALID_CID;
2136   }
2137   return (jint)cid;
2138 }
2139 
register_com_android_bluetooth_btservice_AdapterService(JNIEnv * env)2140 int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
2141   const JNINativeMethod methods[] = {
2142       {"initNative", "(ZZI[Ljava/lang/String;ZLjava/lang/String;)Z",
2143        (void*)initNative},
2144       {"cleanupNative", "()V", (void*)cleanupNative},
2145       {"enableNative", "()Z", (void*)enableNative},
2146       {"disableNative", "()Z", (void*)disableNative},
2147       {"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative},
2148       {"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative},
2149       {"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative},
2150       {"getDevicePropertyNative", "([BI)Z", (void*)getDevicePropertyNative},
2151       {"setDevicePropertyNative", "([BI[B)Z", (void*)setDevicePropertyNative},
2152       {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
2153       {"cancelDiscoveryNative", "()Z", (void*)cancelDiscoveryNative},
2154       {"createBondNative", "([BII)Z", (void*)createBondNative},
2155       {"createBondOutOfBandNative",
2156        "([BILandroid/bluetooth/OobData;Landroid/bluetooth/OobData;)Z",
2157        (void*)createBondOutOfBandNative},
2158       {"removeBondNative", "([B)Z", (void*)removeBondNative},
2159       {"cancelBondNative", "([B)Z", (void*)cancelBondNative},
2160       {"pairingIsBusyNative", "()Z", (void*)pairingIsBusyNative},
2161       {"generateLocalOobDataNative", "(I)V", (void*)generateLocalOobDataNative},
2162       {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative},
2163       {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative},
2164       {"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative},
2165       {"getRemoteServicesNative", "([BI)Z", (void*)getRemoteServicesNative},
2166       {"readEnergyInfoNative", "()I", (void*)readEnergyInfoNative},
2167       {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V",
2168        (void*)dumpNative},
2169       {"dumpMetricsNative", "()[B", (void*)dumpMetricsNative},
2170       {"factoryResetNative", "()Z", (void*)factoryResetNative},
2171       {"obfuscateAddressNative", "([B)[B", (void*)obfuscateAddressNative},
2172       {"setBufferLengthMillisNative", "(II)Z",
2173        (void*)setBufferLengthMillisNative},
2174       {"getMetricIdNative", "([B)I", (void*)getMetricIdNative},
2175       {"connectSocketNative", "([BI[BIII)I", (void*)connectSocketNative},
2176       {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I",
2177        (void*)createSocketChannelNative},
2178       {"requestMaximumTxDataLengthNative", "([B)V",
2179        (void*)requestMaximumTxDataLengthNative},
2180       {"allowLowLatencyAudioNative", "(Z[B)Z",
2181        (void*)allowLowLatencyAudioNative},
2182       {"metadataChangedNative", "([BI[B)V", (void*)metadataChangedNative},
2183       {"isLogRedactionEnabledNative", "()Z",
2184        (void*)isLogRedactionEnabledNative},
2185       {"interopMatchAddrNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
2186        (void*)interopMatchAddrNative},
2187       {"interopMatchNameNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
2188        (void*)interopMatchNameNative},
2189       {"interopMatchAddrOrNameNative",
2190        "(Ljava/lang/String;Ljava/lang/String;)Z",
2191        (void*)interopMatchAddrOrNameNative},
2192       {"interopDatabaseAddRemoveAddrNative",
2193        "(ZLjava/lang/String;Ljava/lang/String;I)V",
2194        (void*)interopDatabaseAddRemoveAddrNative},
2195       {"interopDatabaseAddRemoveNameNative",
2196        "(ZLjava/lang/String;Ljava/lang/String;)V",
2197        (void*)interopDatabaseAddRemoveNameNative},
2198       {"getRemotePbapPceVersionNative", "(Ljava/lang/String;)I",
2199        (void*)getRemotePbapPceVersionNative},
2200       {"pbapPseDynamicVersionUpgradeIsEnabledNative", "()Z",
2201        (void*)pbapPseDynamicVersionUpgradeIsEnabledNative},
2202       {"getSocketL2capLocalChannelIdNative", "(JJ)I",
2203        (void*)getSocketL2capLocalChannelIdNative},
2204       {"getSocketL2capRemoteChannelIdNative", "(JJ)I",
2205        (void*)getSocketL2capRemoteChannelIdNative},
2206   };
2207   const int result = REGISTER_NATIVE_METHODS(
2208       env, "com/android/bluetooth/btservice/AdapterNativeInterface", methods);
2209   if (result != 0) {
2210     return result;
2211   }
2212 
2213   jclass jniAdapterNativeInterfaceClass =
2214       env->FindClass("com/android/bluetooth/btservice/AdapterNativeInterface");
2215   sJniCallbacksField =
2216       env->GetFieldID(jniAdapterNativeInterfaceClass, "mJniCallbacks",
2217                       "Lcom/android/bluetooth/btservice/JniCallbacks;");
2218   env->DeleteLocalRef(jniAdapterNativeInterfaceClass);
2219 
2220   const JNIJavaMethod javaMethods[] = {
2221       {"oobDataReceivedCallback", "(ILandroid/bluetooth/OobData;)V",
2222        &method_oobDataReceivedCallback},
2223       {"stateChangeCallback", "(I)V", &method_stateChangeCallback},
2224       {"adapterPropertyChangedCallback", "([I[[B)V",
2225        &method_adapterPropertyChangedCallback},
2226       {"discoveryStateChangeCallback", "(I)V",
2227        &method_discoveryStateChangeCallback},
2228       {"devicePropertyChangedCallback", "([B[I[[B)V",
2229        &method_devicePropertyChangedCallback},
2230       {"deviceFoundCallback", "([B)V", &method_deviceFoundCallback},
2231       {"pinRequestCallback", "([B[BIZ)V", &method_pinRequestCallback},
2232       {"sspRequestCallback", "([BII)V", &method_sspRequestCallback},
2233       {"bondStateChangeCallback", "(I[BII)V", &method_bondStateChangeCallback},
2234       {"addressConsolidateCallback", "([B[B)V",
2235        &method_addressConsolidateCallback},
2236       {"leAddressAssociateCallback", "([B[B)V",
2237        &method_leAddressAssociateCallback},
2238       {"aclStateChangeCallback", "(I[BIIII)V", &method_aclStateChangeCallback},
2239       {"linkQualityReportCallback", "(JIIIIII)V",
2240        &method_linkQualityReportCallback},
2241       {"switchBufferSizeCallback", "(Z)V", &method_switchBufferSizeCallback},
2242       {"switchCodecCallback", "(Z)V", &method_switchCodecCallback},
2243       {"acquireWakeLock", "(Ljava/lang/String;)Z", &method_acquireWakeLock},
2244       {"releaseWakeLock", "(Ljava/lang/String;)Z", &method_releaseWakeLock},
2245       {"energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V",
2246        &method_energyInfo},
2247       {"keyMissingCallback", "([B)V", &method_keyMissingCallback},
2248   };
2249   GET_JAVA_METHODS(env, "com/android/bluetooth/btservice/JniCallbacks",
2250                    javaMethods);
2251 
2252   const JNIJavaMethod javaUuidTrafficMethods[] = {
2253       {"<init>", "(IJJ)V", &android_bluetooth_UidTraffic.constructor},
2254   };
2255   GET_JAVA_METHODS(env, "android/bluetooth/UidTraffic", javaUuidTrafficMethods);
2256 
2257   if (env->GetJavaVM(&vm) != JNI_OK) {
2258     log::error("Could not get JavaVM");
2259   }
2260 
2261   if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) {
2262     log::error("No Bluetooth Library found");
2263   }
2264 
2265   return 0;
2266 }
2267 
2268 } /* namespace android */
2269 
2270 /*
2271  * JNI Initialization
2272  */
JNI_OnLoad(JavaVM * jvm,void *)2273 jint JNI_OnLoad(JavaVM* jvm, void* /* reserved */) {
2274   /* Set the default logging level for the process using the tag
2275    *  "log.tag.bluetooth" and/or "persist.log.tag.bluetooth" via the android
2276    * logging framework.
2277    */
2278   const char* stack_default_log_tag = "bluetooth";
2279   int default_prio = ANDROID_LOG_INFO;
2280   if (__android_log_is_loggable(ANDROID_LOG_VERBOSE, stack_default_log_tag,
2281                                 default_prio)) {
2282     __android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
2283     log::info("Set stack default log level to 'VERBOSE'");
2284   } else if (__android_log_is_loggable(ANDROID_LOG_DEBUG, stack_default_log_tag,
2285                                        default_prio)) {
2286     __android_log_set_minimum_priority(ANDROID_LOG_DEBUG);
2287     log::info("Set stack default log level to 'DEBUG'");
2288   } else if (__android_log_is_loggable(ANDROID_LOG_INFO, stack_default_log_tag,
2289                                        default_prio)) {
2290     __android_log_set_minimum_priority(ANDROID_LOG_INFO);
2291     log::info("Set stack default log level to 'INFO'");
2292   } else if (__android_log_is_loggable(ANDROID_LOG_WARN, stack_default_log_tag,
2293                                        default_prio)) {
2294     __android_log_set_minimum_priority(ANDROID_LOG_WARN);
2295     log::info("Set stack default log level to 'WARN'");
2296   } else if (__android_log_is_loggable(ANDROID_LOG_ERROR, stack_default_log_tag,
2297                                        default_prio)) {
2298     __android_log_set_minimum_priority(ANDROID_LOG_ERROR);
2299     log::info("Set stack default log level to 'ERROR'");
2300   }
2301 
2302   JNIEnv* e;
2303   int status;
2304 
2305   log::verbose("Bluetooth Adapter Service : loading JNI\n");
2306 
2307   // Check JNI version
2308   if (jvm->GetEnv((void**)&e, JNI_VERSION_1_6)) {
2309     log::error("JNI version mismatch error");
2310     return JNI_ERR;
2311   }
2312 
2313   status = android::register_com_android_bluetooth_btservice_AdapterService(e);
2314   if (status < 0) {
2315     log::error("jni adapter service registration failure, status: {}", status);
2316     return JNI_ERR;
2317   }
2318 
2319   status =
2320       android::register_com_android_bluetooth_btservice_BluetoothKeystore(e);
2321   if (status < 0) {
2322     log::error("jni BluetoothKeyStore registration failure: {}", status);
2323     return JNI_ERR;
2324   }
2325 
2326   status = android::register_com_android_bluetooth_hfp(e);
2327   if (status < 0) {
2328     log::error("jni hfp registration failure, status: {}", status);
2329     return JNI_ERR;
2330   }
2331 
2332   status = android::register_com_android_bluetooth_hfpclient(e);
2333   if (status < 0) {
2334     log::error("jni hfp client registration failure, status: {}", status);
2335     return JNI_ERR;
2336   }
2337 
2338   status = android::register_com_android_bluetooth_a2dp(e);
2339   if (status < 0) {
2340     log::error("jni a2dp source registration failure: {}", status);
2341     return JNI_ERR;
2342   }
2343 
2344   status = android::register_com_android_bluetooth_a2dp_sink(e);
2345   if (status < 0) {
2346     log::error("jni a2dp sink registration failure: {}", status);
2347     return JNI_ERR;
2348   }
2349 
2350   status = android::register_com_android_bluetooth_avrcp_target(e);
2351   if (status < 0) {
2352     log::error("jni new avrcp target registration failure: {}", status);
2353   }
2354 
2355   status = android::register_com_android_bluetooth_avrcp_controller(e);
2356   if (status < 0) {
2357     log::error("jni avrcp controller registration failure: {}", status);
2358     return JNI_ERR;
2359   }
2360 
2361   status = android::register_com_android_bluetooth_hid_host(e);
2362   if (status < 0) {
2363     log::error("jni hid registration failure: {}", status);
2364     return JNI_ERR;
2365   }
2366 
2367   status = android::register_com_android_bluetooth_hid_device(e);
2368   if (status < 0) {
2369     log::error("jni hidd registration failure: {}", status);
2370     return JNI_ERR;
2371   }
2372 
2373   status = android::register_com_android_bluetooth_pan(e);
2374   if (status < 0) {
2375     log::error("jni pan registration failure: {}", status);
2376     return JNI_ERR;
2377   }
2378 
2379   status = android::register_com_android_bluetooth_gatt(e);
2380   if (status < 0) {
2381     log::error("jni gatt registration failure: {}", status);
2382     return JNI_ERR;
2383   }
2384 
2385   status = android::register_com_android_bluetooth_sdp(e);
2386   if (status < 0) {
2387     log::error("jni sdp registration failure: {}", status);
2388     return JNI_ERR;
2389   }
2390 
2391   status = android::register_com_android_bluetooth_hearing_aid(e);
2392   if (status < 0) {
2393     log::error("jni hearing aid registration failure: {}", status);
2394     return JNI_ERR;
2395   }
2396 
2397   status = android::register_com_android_bluetooth_hap_client(e);
2398   if (status < 0) {
2399     log::error("jni le audio hearing access client registration failure: {}",
2400                status);
2401     return JNI_ERR;
2402   }
2403 
2404   status = android::register_com_android_bluetooth_le_audio(e);
2405   if (status < 0) {
2406     log::error("jni le_audio registration failure: {}", status);
2407     return JNI_ERR;
2408   }
2409 
2410   status = android::register_com_android_bluetooth_vc(e);
2411   if (status < 0) {
2412     log::error("jni vc registration failure: {}", status);
2413     return JNI_ERR;
2414   }
2415 
2416   status = android::register_com_android_bluetooth_csip_set_coordinator(e);
2417   if (status < 0) {
2418     log::error("jni csis client registration failure: {}", status);
2419     return JNI_ERR;
2420   }
2421 
2422   status =
2423       android::register_com_android_bluetooth_btservice_BluetoothQualityReport(
2424           e);
2425   if (status < 0) {
2426     log::error("jni bluetooth quality report registration failure: {}", status);
2427     return JNI_ERR;
2428   }
2429 
2430   return JNI_VERSION_1_6;
2431 }
2432 
2433 namespace android {
2434 
2435 /** Load the java methods or die*/
jniGetMethodsOrDie(JNIEnv * env,const char * className,const JNIJavaMethod * methods,int nMethods)2436 void jniGetMethodsOrDie(JNIEnv* env, const char* className,
2437                         const JNIJavaMethod* methods, int nMethods) {
2438   jclass clazz = env->FindClass(className);
2439   if (clazz == nullptr) {
2440     log::fatal("Native registration unable to find class '{}' aborting...",
2441                className);
2442   }
2443 
2444   for (int i = 0; i < nMethods; i++) {
2445     const JNIJavaMethod& method = methods[i];
2446     if (method.is_static) {
2447       *method.id = env->GetStaticMethodID(clazz, method.name, method.signature);
2448     } else {
2449       *method.id = env->GetMethodID(clazz, method.name, method.signature);
2450     }
2451     if (method.id == nullptr) {
2452       log::fatal(
2453           "In class {}: Unable to find '{}' with signature={} is_static={}",
2454           className, method.name, method.signature, method.is_static);
2455     }
2456   }
2457 
2458   env->DeleteLocalRef(clazz);
2459 }
2460 }  // namespace android
2461