1 /*
2  * Copyright (c) 2014 The Android Open Source Project
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 "BluetoothHeadsetClientServiceJni"
19 
20 #include <shared_mutex>
21 
22 #include "com_android_bluetooth.h"
23 #include "hardware/bt_hf_client.h"
24 #include "os/logging/log_adapter.h"
25 
26 namespace android {
27 
28 static bthf_client_interface_t* sBluetoothHfpClientInterface = NULL;
29 static std::shared_mutex interface_mutex;
30 
31 static jobject mCallbacksObj = NULL;
32 static std::shared_mutex callbacks_mutex;
33 
34 static jmethodID method_onConnectionStateChanged;
35 static jmethodID method_onAudioStateChanged;
36 static jmethodID method_onVrStateChanged;
37 static jmethodID method_onNetworkState;
38 static jmethodID method_onNetworkRoaming;
39 static jmethodID method_onNetworkSignal;
40 static jmethodID method_onBatteryLevel;
41 static jmethodID method_onCurrentOperator;
42 static jmethodID method_onCall;
43 static jmethodID method_onCallSetup;
44 static jmethodID method_onCallHeld;
45 static jmethodID method_onRespAndHold;
46 static jmethodID method_onClip;
47 static jmethodID method_onCallWaiting;
48 static jmethodID method_onCurrentCalls;
49 static jmethodID method_onVolumeChange;
50 static jmethodID method_onCmdResult;
51 static jmethodID method_onSubscriberInfo;
52 static jmethodID method_onInBandRing;
53 static jmethodID method_onLastVoiceTagNumber;
54 static jmethodID method_onRingIndication;
55 static jmethodID method_onUnknownEvent;
56 
marshall_bda(const RawAddress * bd_addr)57 static jbyteArray marshall_bda(const RawAddress* bd_addr) {
58   CallbackEnv sCallbackEnv(__func__);
59   if (!sCallbackEnv.valid()) return NULL;
60 
61   jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress));
62   if (!addr) {
63     log::error("Fail to new jbyteArray bd addr");
64     return NULL;
65   }
66   sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress),
67                                    (jbyte*)bd_addr);
68   return addr;
69 }
70 
connection_state_cb(const RawAddress * bd_addr,bthf_client_connection_state_t state,unsigned int peer_feat,unsigned int chld_feat)71 static void connection_state_cb(const RawAddress* bd_addr,
72                                 bthf_client_connection_state_t state,
73                                 unsigned int peer_feat,
74                                 unsigned int chld_feat) {
75   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
76   CallbackEnv sCallbackEnv(__func__);
77   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
78 
79   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
80   if (!addr.get()) return;
81 
82   log::debug("state {} peer_feat {} chld_feat {}", state, peer_feat, chld_feat);
83   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged,
84                                (jint)state, (jint)peer_feat, (jint)chld_feat,
85                                addr.get());
86 }
87 
audio_state_cb(const RawAddress * bd_addr,bthf_client_audio_state_t state)88 static void audio_state_cb(const RawAddress* bd_addr,
89                            bthf_client_audio_state_t state) {
90   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
91   CallbackEnv sCallbackEnv(__func__);
92   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
93 
94   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
95   if (!addr.get()) return;
96 
97   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged,
98                                (jint)state, addr.get());
99 }
100 
vr_cmd_cb(const RawAddress * bd_addr,bthf_client_vr_state_t state)101 static void vr_cmd_cb(const RawAddress* bd_addr, bthf_client_vr_state_t state) {
102   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
103   CallbackEnv sCallbackEnv(__func__);
104   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
105 
106   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
107   if (!addr.get()) return;
108 
109   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged,
110                                (jint)state, addr.get());
111 }
112 
network_state_cb(const RawAddress * bd_addr,bthf_client_network_state_t state)113 static void network_state_cb(const RawAddress* bd_addr,
114                              bthf_client_network_state_t state) {
115   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
116   CallbackEnv sCallbackEnv(__func__);
117   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
118 
119   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
120   if (!addr.get()) return;
121 
122   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNetworkState,
123                                (jint)state, addr.get());
124 }
125 
network_roaming_cb(const RawAddress * bd_addr,bthf_client_service_type_t type)126 static void network_roaming_cb(const RawAddress* bd_addr,
127                                bthf_client_service_type_t type) {
128   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
129   CallbackEnv sCallbackEnv(__func__);
130   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
131 
132   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
133   if (!addr.get()) return;
134 
135   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNetworkRoaming,
136                                (jint)type, addr.get());
137 }
138 
network_signal_cb(const RawAddress * bd_addr,int signal)139 static void network_signal_cb(const RawAddress* bd_addr, int signal) {
140   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
141   CallbackEnv sCallbackEnv(__func__);
142   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
143 
144   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
145   if (!addr.get()) return;
146 
147   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNetworkSignal,
148                                (jint)signal, addr.get());
149 }
150 
battery_level_cb(const RawAddress * bd_addr,int level)151 static void battery_level_cb(const RawAddress* bd_addr, int level) {
152   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
153   CallbackEnv sCallbackEnv(__func__);
154   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
155 
156   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
157   if (!addr.get()) return;
158 
159   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatteryLevel,
160                                (jint)level, addr.get());
161 }
162 
current_operator_cb(const RawAddress * bd_addr,const char * name)163 static void current_operator_cb(const RawAddress* bd_addr, const char* name) {
164   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
165   CallbackEnv sCallbackEnv(__func__);
166   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
167 
168   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
169   if (!addr.get()) return;
170 
171   const char null_str[] = "";
172   if (!sCallbackEnv.isValidUtf(name)) {
173     log::error("name is not a valid UTF string.");
174     name = null_str;
175   }
176 
177   ScopedLocalRef<jstring> js_name(sCallbackEnv.get(),
178                                   sCallbackEnv->NewStringUTF(name));
179   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCurrentOperator,
180                                js_name.get(), addr.get());
181 }
182 
call_cb(const RawAddress * bd_addr,bthf_client_call_t call)183 static void call_cb(const RawAddress* bd_addr, bthf_client_call_t call) {
184   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
185   CallbackEnv sCallbackEnv(__func__);
186   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
187 
188   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
189   if (!addr.get()) return;
190 
191   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCall, (jint)call,
192                                addr.get());
193 }
194 
callsetup_cb(const RawAddress * bd_addr,bthf_client_callsetup_t callsetup)195 static void callsetup_cb(const RawAddress* bd_addr,
196                          bthf_client_callsetup_t callsetup) {
197   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
198   CallbackEnv sCallbackEnv(__func__);
199   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
200 
201   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
202   if (!addr.get()) return;
203 
204   log::debug("callsetup_cb bdaddr {}", *bd_addr);
205 
206   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallSetup,
207                                (jint)callsetup, addr.get());
208 }
209 
callheld_cb(const RawAddress * bd_addr,bthf_client_callheld_t callheld)210 static void callheld_cb(const RawAddress* bd_addr,
211                         bthf_client_callheld_t callheld) {
212   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
213   CallbackEnv sCallbackEnv(__func__);
214   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
215 
216   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
217   if (!addr.get()) return;
218 
219   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallHeld, (jint)callheld,
220                                addr.get());
221 }
222 
resp_and_hold_cb(const RawAddress * bd_addr,bthf_client_resp_and_hold_t resp_and_hold)223 static void resp_and_hold_cb(const RawAddress* bd_addr,
224                              bthf_client_resp_and_hold_t resp_and_hold) {
225   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
226   CallbackEnv sCallbackEnv(__func__);
227   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
228 
229   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
230   if (!addr.get()) return;
231 
232   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRespAndHold,
233                                (jint)resp_and_hold, addr.get());
234 }
235 
clip_cb(const RawAddress * bd_addr,const char * number)236 static void clip_cb(const RawAddress* bd_addr, const char* number) {
237   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
238   CallbackEnv sCallbackEnv(__func__);
239   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
240 
241   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
242   if (!addr.get()) return;
243 
244   const char null_str[] = "";
245   if (!sCallbackEnv.isValidUtf(number)) {
246     log::error("number is not a valid UTF string.");
247     number = null_str;
248   }
249 
250   ScopedLocalRef<jstring> js_number(sCallbackEnv.get(),
251                                     sCallbackEnv->NewStringUTF(number));
252   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClip, js_number.get(),
253                                addr.get());
254 }
255 
call_waiting_cb(const RawAddress * bd_addr,const char * number)256 static void call_waiting_cb(const RawAddress* bd_addr, const char* number) {
257   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
258   CallbackEnv sCallbackEnv(__func__);
259   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
260 
261   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
262   if (!addr.get()) return;
263 
264   const char null_str[] = "";
265   if (!sCallbackEnv.isValidUtf(number)) {
266     log::error("number is not a valid UTF string.");
267     number = null_str;
268   }
269 
270   ScopedLocalRef<jstring> js_number(sCallbackEnv.get(),
271                                     sCallbackEnv->NewStringUTF(number));
272   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallWaiting,
273                                js_number.get(), addr.get());
274 }
275 
current_calls_cb(const RawAddress * bd_addr,int index,bthf_client_call_direction_t dir,bthf_client_call_state_t state,bthf_client_call_mpty_type_t mpty,const char * number)276 static void current_calls_cb(const RawAddress* bd_addr, int index,
277                              bthf_client_call_direction_t dir,
278                              bthf_client_call_state_t state,
279                              bthf_client_call_mpty_type_t mpty,
280                              const char* number) {
281   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
282   CallbackEnv sCallbackEnv(__func__);
283   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
284 
285   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
286   if (!addr.get()) return;
287 
288   const char null_str[] = "";
289   if (!sCallbackEnv.isValidUtf(number)) {
290     log::error("number is not a valid UTF string.");
291     number = null_str;
292   }
293 
294   ScopedLocalRef<jstring> js_number(sCallbackEnv.get(),
295                                     sCallbackEnv->NewStringUTF(number));
296   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCurrentCalls, index, dir,
297                                state, mpty, js_number.get(), addr.get());
298 }
299 
volume_change_cb(const RawAddress * bd_addr,bthf_client_volume_type_t type,int volume)300 static void volume_change_cb(const RawAddress* bd_addr,
301                              bthf_client_volume_type_t type, int volume) {
302   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
303   CallbackEnv sCallbackEnv(__func__);
304   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
305 
306   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
307   if (!addr.get()) return;
308   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChange, (jint)type,
309                                (jint)volume, addr.get());
310 }
311 
cmd_complete_cb(const RawAddress * bd_addr,bthf_client_cmd_complete_t type,int cme)312 static void cmd_complete_cb(const RawAddress* bd_addr,
313                             bthf_client_cmd_complete_t type, int cme) {
314   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
315   CallbackEnv sCallbackEnv(__func__);
316   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
317 
318   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
319   if (!addr.get()) return;
320   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCmdResult, (jint)type,
321                                (jint)cme, addr.get());
322 }
323 
subscriber_info_cb(const RawAddress * bd_addr,const char * name,bthf_client_subscriber_service_type_t type)324 static void subscriber_info_cb(const RawAddress* bd_addr, const char* name,
325                                bthf_client_subscriber_service_type_t type) {
326   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
327   CallbackEnv sCallbackEnv(__func__);
328   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
329 
330   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
331   if (!addr.get()) return;
332 
333   const char null_str[] = "";
334   if (!sCallbackEnv.isValidUtf(name)) {
335     log::error("name is not a valid UTF string.");
336     name = null_str;
337   }
338 
339   ScopedLocalRef<jstring> js_name(sCallbackEnv.get(),
340                                   sCallbackEnv->NewStringUTF(name));
341   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSubscriberInfo,
342                                js_name.get(), (jint)type, addr.get());
343 }
344 
in_band_ring_cb(const RawAddress * bd_addr,bthf_client_in_band_ring_state_t in_band)345 static void in_band_ring_cb(const RawAddress* bd_addr,
346                             bthf_client_in_band_ring_state_t in_band) {
347   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
348   CallbackEnv sCallbackEnv(__func__);
349   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
350 
351   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
352   if (!addr.get()) return;
353   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onInBandRing,
354                                (jint)in_band, addr.get());
355 }
356 
last_voice_tag_number_cb(const RawAddress * bd_addr,const char * number)357 static void last_voice_tag_number_cb(const RawAddress* bd_addr,
358                                      const char* number) {
359   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
360   CallbackEnv sCallbackEnv(__func__);
361   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
362 
363   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
364   if (!addr.get()) return;
365 
366   const char null_str[] = "";
367   if (!sCallbackEnv.isValidUtf(number)) {
368     log::error("number is not a valid UTF string.");
369     number = null_str;
370   }
371 
372   ScopedLocalRef<jstring> js_number(sCallbackEnv.get(),
373                                     sCallbackEnv->NewStringUTF(number));
374   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onLastVoiceTagNumber,
375                                js_number.get(), addr.get());
376 }
377 
ring_indication_cb(const RawAddress * bd_addr)378 static void ring_indication_cb(const RawAddress* bd_addr) {
379   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
380   CallbackEnv sCallbackEnv(__func__);
381   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
382 
383   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
384   if (!addr.get()) return;
385   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRingIndication,
386                                addr.get());
387 }
388 
unknown_event_cb(const RawAddress * bd_addr,const char * eventString)389 static void unknown_event_cb(const RawAddress* bd_addr,
390                              const char* eventString) {
391   std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
392   CallbackEnv sCallbackEnv(__func__);
393   if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
394 
395   ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
396   if (!addr.get()) return;
397 
398   ScopedLocalRef<jstring> js_event(sCallbackEnv.get(),
399                                    sCallbackEnv->NewStringUTF(eventString));
400   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownEvent,
401                                js_event.get(), addr.get());
402 }
403 
404 static bthf_client_callbacks_t sBluetoothHfpClientCallbacks = {
405     sizeof(sBluetoothHfpClientCallbacks),
406     connection_state_cb,
407     audio_state_cb,
408     vr_cmd_cb,
409     network_state_cb,
410     network_roaming_cb,
411     network_signal_cb,
412     battery_level_cb,
413     current_operator_cb,
414     call_cb,
415     callsetup_cb,
416     callheld_cb,
417     resp_and_hold_cb,
418     clip_cb,
419     call_waiting_cb,
420     current_calls_cb,
421     volume_change_cb,
422     cmd_complete_cb,
423     subscriber_info_cb,
424     in_band_ring_cb,
425     last_voice_tag_number_cb,
426     ring_indication_cb,
427     unknown_event_cb,
428 };
429 
initializeNative(JNIEnv * env,jobject object)430 static void initializeNative(JNIEnv* env, jobject object) {
431   log::debug("HfpClient");
432   std::unique_lock<std::shared_mutex> interface_lock(interface_mutex);
433   std::unique_lock<std::shared_mutex> callbacks_lock(callbacks_mutex);
434 
435   const bt_interface_t* btInf = getBluetoothInterface();
436   if (btInf == NULL) {
437     log::error("Bluetooth module is not loaded");
438     return;
439   }
440 
441   if (sBluetoothHfpClientInterface != NULL) {
442     log::warn("Cleaning up Bluetooth HFP Client Interface before initializing");
443     sBluetoothHfpClientInterface->cleanup();
444     sBluetoothHfpClientInterface = NULL;
445   }
446 
447   if (mCallbacksObj != NULL) {
448     log::warn("Cleaning up Bluetooth HFP Client callback object");
449     env->DeleteGlobalRef(mCallbacksObj);
450     mCallbacksObj = NULL;
451   }
452 
453   sBluetoothHfpClientInterface =
454       (bthf_client_interface_t*)btInf->get_profile_interface(
455           BT_PROFILE_HANDSFREE_CLIENT_ID);
456   if (sBluetoothHfpClientInterface == NULL) {
457     log::error("Failed to get Bluetooth HFP Client Interface");
458     return;
459   }
460 
461   bt_status_t status =
462       sBluetoothHfpClientInterface->init(&sBluetoothHfpClientCallbacks);
463   if (status != BT_STATUS_SUCCESS) {
464     log::error("Failed to initialize Bluetooth HFP Client, status: {}",
465                bt_status_text(status));
466     sBluetoothHfpClientInterface = NULL;
467     return;
468   }
469 
470   mCallbacksObj = env->NewGlobalRef(object);
471 }
472 
cleanupNative(JNIEnv * env,jobject)473 static void cleanupNative(JNIEnv* env, jobject /* object */) {
474   std::unique_lock<std::shared_mutex> interface_lock(interface_mutex);
475   std::unique_lock<std::shared_mutex> callbacks_lock(callbacks_mutex);
476 
477   const bt_interface_t* btInf = getBluetoothInterface();
478   if (btInf == NULL) {
479     log::error("Bluetooth module is not loaded");
480     return;
481   }
482 
483   if (sBluetoothHfpClientInterface != NULL) {
484     log::warn("Cleaning up Bluetooth HFP Client Interface...");
485     sBluetoothHfpClientInterface->cleanup();
486     sBluetoothHfpClientInterface = NULL;
487   }
488 
489   if (mCallbacksObj != NULL) {
490     log::warn("Cleaning up Bluetooth HFP Client callback object");
491     env->DeleteGlobalRef(mCallbacksObj);
492     mCallbacksObj = NULL;
493   }
494 }
495 
connectNative(JNIEnv * env,jobject,jbyteArray address)496 static jboolean connectNative(JNIEnv* env, jobject /* object */,
497                               jbyteArray address) {
498   std::shared_lock<std::shared_mutex> lock(interface_mutex);
499   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
500 
501   jbyte* addr = env->GetByteArrayElements(address, NULL);
502   if (!addr) {
503     jniThrowIOException(env, EINVAL);
504     return JNI_FALSE;
505   }
506 
507   bt_status_t status =
508       sBluetoothHfpClientInterface->connect((const RawAddress*)addr);
509   if (status != BT_STATUS_SUCCESS) {
510     log::error("Failed AG connection, status: {}", bt_status_text(status));
511   }
512   env->ReleaseByteArrayElements(address, addr, 0);
513   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
514 }
515 
disconnectNative(JNIEnv * env,jobject,jbyteArray address)516 static jboolean disconnectNative(JNIEnv* env, jobject /* object */,
517                                  jbyteArray address) {
518   std::shared_lock<std::shared_mutex> lock(interface_mutex);
519   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
520 
521   jbyte* addr = env->GetByteArrayElements(address, NULL);
522   if (!addr) {
523     jniThrowIOException(env, EINVAL);
524     return JNI_FALSE;
525   }
526 
527   bt_status_t status =
528       sBluetoothHfpClientInterface->disconnect((const RawAddress*)addr);
529   if (status != BT_STATUS_SUCCESS) {
530     log::error("Failed AG disconnection, status: {}", bt_status_text(status));
531   }
532   env->ReleaseByteArrayElements(address, addr, 0);
533   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
534 }
535 
connectAudioNative(JNIEnv * env,jobject,jbyteArray address)536 static jboolean connectAudioNative(JNIEnv* env, jobject /* object */,
537                                    jbyteArray address) {
538   std::shared_lock<std::shared_mutex> lock(interface_mutex);
539   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
540 
541   jbyte* addr = env->GetByteArrayElements(address, NULL);
542   if (!addr) {
543     jniThrowIOException(env, EINVAL);
544     return JNI_FALSE;
545   }
546 
547   bt_status_t status =
548       sBluetoothHfpClientInterface->connect_audio((const RawAddress*)addr);
549   if (status != BT_STATUS_SUCCESS) {
550     log::error("Failed AG audio connection, status: {}",
551                bt_status_text(status));
552   }
553   env->ReleaseByteArrayElements(address, addr, 0);
554   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
555 }
556 
disconnectAudioNative(JNIEnv * env,jobject,jbyteArray address)557 static jboolean disconnectAudioNative(JNIEnv* env, jobject /* object */,
558                                       jbyteArray address) {
559   std::shared_lock<std::shared_mutex> lock(interface_mutex);
560   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
561 
562   jbyte* addr = env->GetByteArrayElements(address, NULL);
563   if (!addr) {
564     jniThrowIOException(env, EINVAL);
565     return JNI_FALSE;
566   }
567 
568   bt_status_t status =
569       sBluetoothHfpClientInterface->disconnect_audio((const RawAddress*)addr);
570   if (status != BT_STATUS_SUCCESS) {
571     log::error("Failed AG audio disconnection, status: {}",
572                bt_status_text(status));
573   }
574   env->ReleaseByteArrayElements(address, addr, 0);
575   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
576 }
577 
startVoiceRecognitionNative(JNIEnv * env,jobject,jbyteArray address)578 static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject /* object */,
579                                             jbyteArray address) {
580   std::shared_lock<std::shared_mutex> lock(interface_mutex);
581   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
582 
583   jbyte* addr = env->GetByteArrayElements(address, NULL);
584   if (!addr) {
585     jniThrowIOException(env, EINVAL);
586     return JNI_FALSE;
587   }
588 
589   bt_status_t status = sBluetoothHfpClientInterface->start_voice_recognition(
590       (const RawAddress*)addr);
591   if (status != BT_STATUS_SUCCESS) {
592     log::error("Failed to start voice recognition, status: {}",
593                bt_status_text(status));
594   }
595   env->ReleaseByteArrayElements(address, addr, 0);
596   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
597 }
598 
stopVoiceRecognitionNative(JNIEnv * env,jobject,jbyteArray address)599 static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject /* object */,
600                                            jbyteArray address) {
601   std::shared_lock<std::shared_mutex> lock(interface_mutex);
602   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
603 
604   jbyte* addr = env->GetByteArrayElements(address, NULL);
605   if (!addr) {
606     jniThrowIOException(env, EINVAL);
607     return JNI_FALSE;
608   }
609 
610   bt_status_t status = sBluetoothHfpClientInterface->stop_voice_recognition(
611       (const RawAddress*)addr);
612   if (status != BT_STATUS_SUCCESS) {
613     log::error("Failed to stop voice recognition, status: {}",
614                bt_status_text(status));
615   }
616   env->ReleaseByteArrayElements(address, addr, 0);
617   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
618 }
619 
setVolumeNative(JNIEnv * env,jobject,jbyteArray address,jint volume_type,jint volume)620 static jboolean setVolumeNative(JNIEnv* env, jobject /* object */,
621                                 jbyteArray address, jint volume_type,
622                                 jint volume) {
623   std::shared_lock<std::shared_mutex> lock(interface_mutex);
624   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
625 
626   jbyte* addr = env->GetByteArrayElements(address, NULL);
627   if (!addr) {
628     jniThrowIOException(env, EINVAL);
629     return JNI_FALSE;
630   }
631 
632   bt_status_t status = sBluetoothHfpClientInterface->volume_control(
633       (const RawAddress*)addr, (bthf_client_volume_type_t)volume_type, volume);
634   if (status != BT_STATUS_SUCCESS) {
635     log::error("FAILED to control volume, status: {}", bt_status_text(status));
636   }
637   env->ReleaseByteArrayElements(address, addr, 0);
638   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
639 }
640 
dialNative(JNIEnv * env,jobject,jbyteArray address,jstring number_str)641 static jboolean dialNative(JNIEnv* env, jobject /* object */,
642                            jbyteArray address, jstring number_str) {
643   std::shared_lock<std::shared_mutex> lock(interface_mutex);
644   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
645 
646   jbyte* addr = env->GetByteArrayElements(address, NULL);
647   if (!addr) {
648     jniThrowIOException(env, EINVAL);
649     return JNI_FALSE;
650   }
651 
652   const char* number = nullptr;
653   if (number_str != nullptr) {
654     number = env->GetStringUTFChars(number_str, nullptr);
655   }
656   bt_status_t status =
657     sBluetoothHfpClientInterface->dial((const RawAddress*)addr,
658                                        number == nullptr ? "" : number);
659 
660   if (status != BT_STATUS_SUCCESS) {
661     log::error("Failed to dial, status: {}", bt_status_text(status));
662   }
663   if (number != nullptr) {
664     env->ReleaseStringUTFChars(number_str, number);
665   }
666   env->ReleaseByteArrayElements(address, addr, 0);
667   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
668 }
669 
dialMemoryNative(JNIEnv * env,jobject,jbyteArray address,jint location)670 static jboolean dialMemoryNative(JNIEnv* env, jobject /* object */,
671                                  jbyteArray address, jint location) {
672   std::shared_lock<std::shared_mutex> lock(interface_mutex);
673   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
674 
675   jbyte* addr = env->GetByteArrayElements(address, NULL);
676   if (!addr) {
677     jniThrowIOException(env, EINVAL);
678     return JNI_FALSE;
679   }
680 
681   bt_status_t status = sBluetoothHfpClientInterface->dial_memory(
682       (const RawAddress*)addr, (int)location);
683   if (status != BT_STATUS_SUCCESS) {
684     log::error("Failed to dial from memory, status: {}",
685                bt_status_text(status));
686   }
687 
688   env->ReleaseByteArrayElements(address, addr, 0);
689   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
690 }
691 
handleCallActionNative(JNIEnv * env,jobject,jbyteArray address,jint action,jint index)692 static jboolean handleCallActionNative(JNIEnv* env, jobject /* object */,
693                                        jbyteArray address, jint action,
694                                        jint index) {
695   std::shared_lock<std::shared_mutex> lock(interface_mutex);
696   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
697 
698   jbyte* addr = env->GetByteArrayElements(address, NULL);
699   if (!addr) {
700     jniThrowIOException(env, EINVAL);
701     return JNI_FALSE;
702   }
703 
704   bt_status_t status = sBluetoothHfpClientInterface->handle_call_action(
705       (const RawAddress*)addr, (bthf_client_call_action_t)action, (int)index);
706 
707   if (status != BT_STATUS_SUCCESS) {
708     log::error("Failed to enter private mode, status: {}",
709                bt_status_text(status));
710   }
711   env->ReleaseByteArrayElements(address, addr, 0);
712   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
713 }
714 
queryCurrentCallsNative(JNIEnv * env,jobject,jbyteArray address)715 static jboolean queryCurrentCallsNative(JNIEnv* env, jobject /* object */,
716                                         jbyteArray address) {
717   std::shared_lock<std::shared_mutex> lock(interface_mutex);
718   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
719 
720   jbyte* addr = env->GetByteArrayElements(address, NULL);
721   if (!addr) {
722     jniThrowIOException(env, EINVAL);
723     return JNI_FALSE;
724   }
725 
726   bt_status_t status = sBluetoothHfpClientInterface->query_current_calls(
727       (const RawAddress*)addr);
728 
729   if (status != BT_STATUS_SUCCESS) {
730     log::error("Failed to query current calls, status: {}",
731                bt_status_text(status));
732   }
733   env->ReleaseByteArrayElements(address, addr, 0);
734   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
735 }
736 
queryCurrentOperatorNameNative(JNIEnv * env,jobject,jbyteArray address)737 static jboolean queryCurrentOperatorNameNative(JNIEnv* env,
738                                                jobject /* object */,
739                                                jbyteArray address) {
740   std::shared_lock<std::shared_mutex> lock(interface_mutex);
741   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
742 
743   jbyte* addr = env->GetByteArrayElements(address, NULL);
744   if (!addr) {
745     jniThrowIOException(env, EINVAL);
746     return JNI_FALSE;
747   }
748 
749   bt_status_t status =
750       sBluetoothHfpClientInterface->query_current_operator_name(
751           (const RawAddress*)addr);
752   if (status != BT_STATUS_SUCCESS) {
753     log::error("Failed to query current operator name, status: {}",
754                bt_status_text(status));
755   }
756 
757   env->ReleaseByteArrayElements(address, addr, 0);
758   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
759 }
760 
retrieveSubscriberInfoNative(JNIEnv * env,jobject,jbyteArray address)761 static jboolean retrieveSubscriberInfoNative(JNIEnv* env, jobject /* object */,
762                                              jbyteArray address) {
763   std::shared_lock<std::shared_mutex> lock(interface_mutex);
764   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
765 
766   jbyte* addr = env->GetByteArrayElements(address, NULL);
767   if (!addr) {
768     jniThrowIOException(env, EINVAL);
769     return JNI_FALSE;
770   }
771 
772   bt_status_t status = sBluetoothHfpClientInterface->retrieve_subscriber_info(
773       (const RawAddress*)addr);
774   if (status != BT_STATUS_SUCCESS) {
775     log::error("Failed to retrieve subscriber info, status: {}",
776                bt_status_text(status));
777   }
778 
779   env->ReleaseByteArrayElements(address, addr, 0);
780   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
781 }
782 
sendDtmfNative(JNIEnv * env,jobject,jbyteArray address,jbyte code)783 static jboolean sendDtmfNative(JNIEnv* env, jobject /* object */,
784                                jbyteArray address, jbyte code) {
785   std::shared_lock<std::shared_mutex> lock(interface_mutex);
786   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
787 
788   jbyte* addr = env->GetByteArrayElements(address, NULL);
789   if (!addr) {
790     jniThrowIOException(env, EINVAL);
791     return JNI_FALSE;
792   }
793 
794   bt_status_t status = sBluetoothHfpClientInterface->send_dtmf(
795       (const RawAddress*)addr, (char)code);
796   if (status != BT_STATUS_SUCCESS) {
797     log::error("Failed to send DTMF, status: {}", bt_status_text(status));
798   }
799 
800   env->ReleaseByteArrayElements(address, addr, 0);
801   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
802 }
803 
requestLastVoiceTagNumberNative(JNIEnv * env,jobject,jbyteArray address)804 static jboolean requestLastVoiceTagNumberNative(JNIEnv* env,
805                                                 jobject /* object */,
806                                                 jbyteArray address) {
807   std::shared_lock<std::shared_mutex> lock(interface_mutex);
808   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
809 
810   jbyte* addr = env->GetByteArrayElements(address, NULL);
811   if (!addr) {
812     jniThrowIOException(env, EINVAL);
813     return JNI_FALSE;
814   }
815 
816   bt_status_t status =
817       sBluetoothHfpClientInterface->request_last_voice_tag_number(
818           (const RawAddress*)addr);
819 
820   if (status != BT_STATUS_SUCCESS) {
821     log::error("Failed to request last Voice Tag number, status: {}",
822                bt_status_text(status));
823   }
824 
825   env->ReleaseByteArrayElements(address, addr, 0);
826   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
827 }
828 
sendATCmdNative(JNIEnv * env,jobject,jbyteArray address,jint cmd,jint val1,jint val2,jstring arg_str)829 static jboolean sendATCmdNative(JNIEnv* env, jobject /* object */,
830                                 jbyteArray address, jint cmd, jint val1,
831                                 jint val2, jstring arg_str) {
832   std::shared_lock<std::shared_mutex> lock(interface_mutex);
833   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
834 
835   jbyte* addr = env->GetByteArrayElements(address, NULL);
836   if (!addr) {
837     jniThrowIOException(env, EINVAL);
838     return JNI_FALSE;
839   }
840   const char* arg = NULL;
841   if (arg_str != NULL) {
842     arg = env->GetStringUTFChars(arg_str, NULL);
843   }
844 
845   bt_status_t status = sBluetoothHfpClientInterface->send_at_cmd(
846       (const RawAddress*)addr, cmd, val1, val2, arg);
847 
848   if (status != BT_STATUS_SUCCESS) {
849     log::error("Failed to send cmd, status: {}", bt_status_text(status));
850   }
851 
852   if (arg != NULL) {
853     env->ReleaseStringUTFChars(arg_str, arg);
854   }
855 
856   env->ReleaseByteArrayElements(address, addr, 0);
857   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
858 }
859 
sendAndroidAtNative(JNIEnv * env,jobject,jbyteArray address,jstring arg_str)860 static jboolean sendAndroidAtNative(JNIEnv* env, jobject /* object */,
861                                     jbyteArray address, jstring arg_str) {
862   std::shared_lock<std::shared_mutex> lock(interface_mutex);
863   if (!sBluetoothHfpClientInterface) return JNI_FALSE;
864 
865   jbyte* addr = env->GetByteArrayElements(address, NULL);
866   if (!addr) {
867     jniThrowIOException(env, EINVAL);
868     return JNI_FALSE;
869   }
870 
871   const char* arg = NULL;
872   if (arg_str != NULL) {
873     arg = env->GetStringUTFChars(arg_str, NULL);
874   }
875 
876   bt_status_t status = sBluetoothHfpClientInterface->send_android_at(
877       (const RawAddress*)addr, arg);
878 
879   if (status != BT_STATUS_SUCCESS) {
880     log::error("FAILED to control volume, status: {}", bt_status_text(status));
881   }
882 
883   if (arg != NULL) {
884     env->ReleaseStringUTFChars(arg_str, arg);
885   }
886 
887   env->ReleaseByteArrayElements(address, addr, 0);
888   return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
889 }
890 
register_com_android_bluetooth_hfpclient(JNIEnv * env)891 int register_com_android_bluetooth_hfpclient(JNIEnv* env) {
892   const JNINativeMethod methods[] = {
893       {"initializeNative", "()V", (void*)initializeNative},
894       {"cleanupNative", "()V", (void*)cleanupNative},
895       {"connectNative", "([B)Z", (void*)connectNative},
896       {"disconnectNative", "([B)Z", (void*)disconnectNative},
897       {"connectAudioNative", "([B)Z", (void*)connectAudioNative},
898       {"disconnectAudioNative", "([B)Z", (void*)disconnectAudioNative},
899       {"startVoiceRecognitionNative", "([B)Z",
900        (void*)startVoiceRecognitionNative},
901       {"stopVoiceRecognitionNative", "([B)Z",
902        (void*)stopVoiceRecognitionNative},
903       {"setVolumeNative", "([BII)Z", (void*)setVolumeNative},
904       {"dialNative", "([BLjava/lang/String;)Z", (void*)dialNative},
905       {"dialMemoryNative", "([BI)Z", (void*)dialMemoryNative},
906       {"handleCallActionNative", "([BII)Z", (void*)handleCallActionNative},
907       {"queryCurrentCallsNative", "([B)Z", (void*)queryCurrentCallsNative},
908       {"queryCurrentOperatorNameNative", "([B)Z",
909        (void*)queryCurrentOperatorNameNative},
910       {"retrieveSubscriberInfoNative", "([B)Z",
911        (void*)retrieveSubscriberInfoNative},
912       {"sendDtmfNative", "([BB)Z", (void*)sendDtmfNative},
913       {"requestLastVoiceTagNumberNative", "([B)Z",
914        (void*)requestLastVoiceTagNumberNative},
915       {"sendATCmdNative", "([BIIILjava/lang/String;)Z", (void*)sendATCmdNative},
916       {"sendAndroidAtNative", "([BLjava/lang/String;)Z",
917        (void*)sendAndroidAtNative},
918   };
919   const int result = REGISTER_NATIVE_METHODS(
920       env, "com/android/bluetooth/hfpclient/NativeInterface", methods);
921   if (result != 0) {
922     return result;
923   }
924 
925   const JNIJavaMethod javaMethods[] = {
926       {"onConnectionStateChanged", "(III[B)V",
927        &method_onConnectionStateChanged},
928       {"onAudioStateChanged", "(I[B)V", &method_onAudioStateChanged},
929       {"onVrStateChanged", "(I[B)V", &method_onVrStateChanged},
930       {"onNetworkState", "(I[B)V", &method_onNetworkState},
931       {"onNetworkRoaming", "(I[B)V", &method_onNetworkRoaming},
932       {"onNetworkSignal", "(I[B)V", &method_onNetworkSignal},
933       {"onBatteryLevel", "(I[B)V", &method_onBatteryLevel},
934       {"onCurrentOperator", "(Ljava/lang/String;[B)V",
935        &method_onCurrentOperator},
936       {"onCall", "(I[B)V", &method_onCall},
937       {"onCallSetup", "(I[B)V", &method_onCallSetup},
938       {"onCallHeld", "(I[B)V", &method_onCallHeld},
939       {"onRespAndHold", "(I[B)V", &method_onRespAndHold},
940       {"onClip", "(Ljava/lang/String;[B)V", &method_onClip},
941       {"onCallWaiting", "(Ljava/lang/String;[B)V", &method_onCallWaiting},
942       {"onCurrentCalls", "(IIIILjava/lang/String;[B)V", &method_onCurrentCalls},
943       {"onVolumeChange", "(II[B)V", &method_onVolumeChange},
944       {"onCmdResult", "(II[B)V", &method_onCmdResult},
945       {"onSubscriberInfo", "(Ljava/lang/String;I[B)V",
946        &method_onSubscriberInfo},
947       {"onInBandRing", "(I[B)V", &method_onInBandRing},
948       {"onLastVoiceTagNumber", "(Ljava/lang/String;[B)V",
949        &method_onLastVoiceTagNumber},
950       {"onRingIndication", "([B)V", &method_onRingIndication},
951       {"onUnknownEvent", "(Ljava/lang/String;[B)V", &method_onUnknownEvent},
952   };
953   GET_JAVA_METHODS(env, "com/android/bluetooth/hfpclient/NativeInterface",
954                    javaMethods);
955 
956   return 0;
957 }
958 
959 } /* namespace android */
960