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