1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "BluetoothHeadsetServiceJni" 18 19 #define LOG_NDEBUG 0 20 21 #include "android_runtime/AndroidRuntime.h" 22 #include "com_android_bluetooth.h" 23 #include "hardware/bluetooth_headset_callbacks.h" 24 #include "hardware/bluetooth_headset_interface.h" 25 #include "hardware/bt_hf.h" 26 #include "utils/Log.h" 27 28 #include <mutex> 29 #include <shared_mutex> 30 31 namespace android { 32 33 static jmethodID method_onConnectionStateChanged; 34 static jmethodID method_onAudioStateChanged; 35 static jmethodID method_onVrStateChanged; 36 static jmethodID method_onAnswerCall; 37 static jmethodID method_onHangupCall; 38 static jmethodID method_onVolumeChanged; 39 static jmethodID method_onDialCall; 40 static jmethodID method_onSendDtmf; 41 static jmethodID method_onNoiceReductionEnable; 42 static jmethodID method_onWBS; 43 static jmethodID method_onAtChld; 44 static jmethodID method_onAtCnum; 45 static jmethodID method_onAtCind; 46 static jmethodID method_onAtCops; 47 static jmethodID method_onAtClcc; 48 static jmethodID method_onUnknownAt; 49 static jmethodID method_onKeyPressed; 50 static jmethodID method_onAtBind; 51 static jmethodID method_onAtBiev; 52 static jmethodID method_onAtBia; 53 54 static bluetooth::headset::Interface* sBluetoothHfpInterface = nullptr; 55 static std::shared_timed_mutex interface_mutex; 56 57 static jobject mCallbacksObj = nullptr; 58 static std::shared_timed_mutex callbacks_mutex; 59 60 static jbyteArray marshall_bda(RawAddress* bd_addr) { 61 CallbackEnv sCallbackEnv(__func__); 62 if (!sCallbackEnv.valid()) return nullptr; 63 64 jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress)); 65 if (!addr) { 66 ALOGE("Fail to new jbyteArray bd addr"); 67 return nullptr; 68 } 69 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress), 70 (jbyte*)bd_addr); 71 return addr; 72 } 73 74 class JniHeadsetCallbacks : bluetooth::headset::Callbacks { 75 public: 76 static bluetooth::headset::Callbacks* GetInstance() { 77 static bluetooth::headset::Callbacks* instance = new JniHeadsetCallbacks(); 78 return instance; 79 } 80 81 void ConnectionStateCallback( 82 bluetooth::headset::bthf_connection_state_t state, 83 RawAddress* bd_addr) override { 84 ALOGI("%s %d for %s", __func__, state, bd_addr->ToString().c_str()); 85 86 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 87 CallbackEnv sCallbackEnv(__func__); 88 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 89 90 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 91 if (!addr.get()) return; 92 93 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, 94 (jint)state, addr.get()); 95 } 96 97 void AudioStateCallback(bluetooth::headset::bthf_audio_state_t state, 98 RawAddress* bd_addr) override { 99 ALOGI("%s, %d for %s", __func__, state, bd_addr->ToString().c_str()); 100 101 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 102 CallbackEnv sCallbackEnv(__func__); 103 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 104 105 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 106 if (!addr.get()) return; 107 108 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, 109 (jint)state, addr.get()); 110 } 111 112 void VoiceRecognitionCallback(bluetooth::headset::bthf_vr_state_t state, 113 RawAddress* bd_addr) override { 114 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 115 CallbackEnv sCallbackEnv(__func__); 116 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 117 118 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 119 if (!addr.get()) { 120 ALOGE("Fail to new jbyteArray bd addr for audio state"); 121 return; 122 } 123 124 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, 125 (jint)state, addr.get()); 126 } 127 128 void AnswerCallCallback(RawAddress* bd_addr) override { 129 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 130 CallbackEnv sCallbackEnv(__func__); 131 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 132 133 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 134 if (!addr.get()) { 135 ALOGE("Fail to new jbyteArray bd addr for audio state"); 136 return; 137 } 138 139 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall, 140 addr.get()); 141 } 142 143 void HangupCallCallback(RawAddress* bd_addr) override { 144 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 145 CallbackEnv sCallbackEnv(__func__); 146 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 147 148 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 149 if (!addr.get()) { 150 ALOGE("Fail to new jbyteArray bd addr for audio state"); 151 return; 152 } 153 154 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHangupCall, 155 addr.get()); 156 } 157 158 void VolumeControlCallback(bluetooth::headset::bthf_volume_type_t type, 159 int volume, RawAddress* bd_addr) override { 160 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 161 CallbackEnv sCallbackEnv(__func__); 162 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 163 164 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 165 if (!addr.get()) { 166 ALOGE("Fail to new jbyteArray bd addr for audio state"); 167 return; 168 } 169 170 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChanged, 171 (jint)type, (jint)volume, addr.get()); 172 } 173 174 void DialCallCallback(char* number, RawAddress* bd_addr) override { 175 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 176 CallbackEnv sCallbackEnv(__func__); 177 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 178 179 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 180 if (!addr.get()) { 181 ALOGE("Fail to new jbyteArray bd addr for audio state"); 182 return; 183 } 184 185 ScopedLocalRef<jstring> js_number(sCallbackEnv.get(), 186 sCallbackEnv->NewStringUTF(number)); 187 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDialCall, 188 js_number.get(), addr.get()); 189 } 190 191 void DtmfCmdCallback(char dtmf, RawAddress* bd_addr) override { 192 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 193 CallbackEnv sCallbackEnv(__func__); 194 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 195 196 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 197 if (!addr.get()) { 198 ALOGE("Fail to new jbyteArray bd addr for audio state"); 199 return; 200 } 201 202 // TBD dtmf has changed from int to char 203 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf, 204 addr.get()); 205 } 206 207 void NoiseReductionCallback(bluetooth::headset::bthf_nrec_t nrec, 208 RawAddress* bd_addr) override { 209 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 210 CallbackEnv sCallbackEnv(__func__); 211 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 212 213 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 214 if (!addr.get()) { 215 ALOGE("Fail to new jbyteArray bd addr for audio state"); 216 return; 217 } 218 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiceReductionEnable, 219 nrec == bluetooth::headset::BTHF_NREC_START, 220 addr.get()); 221 } 222 223 void WbsCallback(bluetooth::headset::bthf_wbs_config_t wbs_config, 224 RawAddress* bd_addr) override { 225 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 226 CallbackEnv sCallbackEnv(__func__); 227 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 228 229 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 230 if (addr.get() == nullptr) return; 231 232 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWBS, wbs_config, 233 addr.get()); 234 } 235 236 void AtChldCallback(bluetooth::headset::bthf_chld_type_t chld, 237 RawAddress* bd_addr) override { 238 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 239 CallbackEnv sCallbackEnv(__func__); 240 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 241 242 ScopedLocalRef<jbyteArray> addr( 243 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); 244 if (!addr.get()) { 245 ALOGE("Fail to new jbyteArray bd addr for audio state"); 246 return; 247 } 248 249 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), 250 (jbyte*)bd_addr); 251 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld, 252 addr.get()); 253 } 254 255 void AtCnumCallback(RawAddress* bd_addr) override { 256 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 257 CallbackEnv sCallbackEnv(__func__); 258 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 259 260 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 261 if (!addr.get()) { 262 ALOGE("Fail to new jbyteArray bd addr for audio state"); 263 return; 264 } 265 266 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum, addr.get()); 267 } 268 269 void AtCindCallback(RawAddress* bd_addr) override { 270 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 271 CallbackEnv sCallbackEnv(__func__); 272 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 273 274 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 275 if (!addr.get()) { 276 ALOGE("Fail to new jbyteArray bd addr for audio state"); 277 return; 278 } 279 280 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind, addr.get()); 281 } 282 283 void AtCopsCallback(RawAddress* bd_addr) override { 284 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 285 CallbackEnv sCallbackEnv(__func__); 286 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 287 288 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 289 if (!addr.get()) { 290 ALOGE("Fail to new jbyteArray bd addr for audio state"); 291 return; 292 } 293 294 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops, addr.get()); 295 } 296 297 void AtClccCallback(RawAddress* bd_addr) override { 298 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 299 CallbackEnv sCallbackEnv(__func__); 300 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 301 302 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 303 if (!addr.get()) { 304 ALOGE("Fail to new jbyteArray bd addr for audio state"); 305 return; 306 } 307 308 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc, addr.get()); 309 } 310 311 void UnknownAtCallback(char* at_string, RawAddress* bd_addr) override { 312 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 313 CallbackEnv sCallbackEnv(__func__); 314 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 315 316 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 317 if (!addr.get()) { 318 ALOGE("Fail to new jbyteArray bd addr for audio state"); 319 return; 320 } 321 322 ScopedLocalRef<jstring> js_at_string(sCallbackEnv.get(), 323 sCallbackEnv->NewStringUTF(at_string)); 324 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownAt, 325 js_at_string.get(), addr.get()); 326 } 327 328 void KeyPressedCallback(RawAddress* bd_addr) override { 329 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 330 CallbackEnv sCallbackEnv(__func__); 331 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 332 333 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 334 if (!addr.get()) { 335 ALOGE("Fail to new jbyteArray bd addr for audio state"); 336 return; 337 } 338 339 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed, 340 addr.get()); 341 } 342 343 void AtBindCallback(char* at_string, RawAddress* bd_addr) override { 344 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 345 CallbackEnv sCallbackEnv(__func__); 346 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 347 348 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 349 if (addr.get() == nullptr) return; 350 351 ScopedLocalRef<jstring> js_at_string(sCallbackEnv.get(), 352 sCallbackEnv->NewStringUTF(at_string)); 353 354 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBind, 355 js_at_string.get(), addr.get()); 356 } 357 358 void AtBievCallback(bluetooth::headset::bthf_hf_ind_type_t ind_id, 359 int ind_value, RawAddress* bd_addr) override { 360 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 361 CallbackEnv sCallbackEnv(__func__); 362 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 363 364 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 365 if (addr.get() == nullptr) return; 366 367 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBiev, ind_id, 368 (jint)ind_value, addr.get()); 369 } 370 371 void AtBiaCallback(bool service, bool roam, bool signal, bool battery, 372 RawAddress* bd_addr) override { 373 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); 374 CallbackEnv sCallbackEnv(__func__); 375 if (!sCallbackEnv.valid() || !mCallbacksObj) return; 376 377 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 378 if (addr.get() == nullptr) return; 379 380 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBia, service, roam, 381 signal, battery, addr.get()); 382 } 383 }; 384 385 static void classInitNative(JNIEnv* env, jclass clazz) { 386 method_onConnectionStateChanged = 387 env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V"); 388 method_onAudioStateChanged = 389 env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V"); 390 method_onVrStateChanged = 391 env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V"); 392 method_onAnswerCall = env->GetMethodID(clazz, "onAnswerCall", "([B)V"); 393 method_onHangupCall = env->GetMethodID(clazz, "onHangupCall", "([B)V"); 394 method_onVolumeChanged = 395 env->GetMethodID(clazz, "onVolumeChanged", "(II[B)V"); 396 method_onDialCall = 397 env->GetMethodID(clazz, "onDialCall", "(Ljava/lang/String;[B)V"); 398 method_onSendDtmf = env->GetMethodID(clazz, "onSendDtmf", "(I[B)V"); 399 method_onNoiceReductionEnable = 400 env->GetMethodID(clazz, "onNoiceReductionEnable", "(Z[B)V"); 401 method_onWBS = env->GetMethodID(clazz, "onWBS", "(I[B)V"); 402 method_onAtChld = env->GetMethodID(clazz, "onAtChld", "(I[B)V"); 403 method_onAtCnum = env->GetMethodID(clazz, "onAtCnum", "([B)V"); 404 method_onAtCind = env->GetMethodID(clazz, "onAtCind", "([B)V"); 405 method_onAtCops = env->GetMethodID(clazz, "onAtCops", "([B)V"); 406 method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "([B)V"); 407 method_onUnknownAt = 408 env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;[B)V"); 409 method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "([B)V"); 410 method_onAtBind = 411 env->GetMethodID(clazz, "onATBind", "(Ljava/lang/String;[B)V"); 412 method_onAtBiev = env->GetMethodID(clazz, "onATBiev", "(II[B)V"); 413 method_onAtBia = env->GetMethodID(clazz, "onAtBia", "(ZZZZ[B)V"); 414 415 ALOGI("%s: succeeds", __func__); 416 } 417 418 static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients, 419 jboolean inband_ringing_enabled) { 420 std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex); 421 std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex); 422 423 const bt_interface_t* btInf = getBluetoothInterface(); 424 if (!btInf) { 425 ALOGE("%s: Bluetooth module is not loaded", __func__); 426 jniThrowIOException(env, EINVAL); 427 return; 428 } 429 430 if (sBluetoothHfpInterface) { 431 ALOGI("%s: Cleaning up Bluetooth Handsfree Interface before initializing", 432 __func__); 433 sBluetoothHfpInterface->Cleanup(); 434 sBluetoothHfpInterface = nullptr; 435 } 436 437 if (mCallbacksObj) { 438 ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__); 439 env->DeleteGlobalRef(mCallbacksObj); 440 mCallbacksObj = nullptr; 441 } 442 443 sBluetoothHfpInterface = 444 (bluetooth::headset::Interface*)btInf->get_profile_interface( 445 BT_PROFILE_HANDSFREE_ID); 446 if (!sBluetoothHfpInterface) { 447 ALOGW("%s: Failed to get Bluetooth Handsfree Interface", __func__); 448 jniThrowIOException(env, EINVAL); 449 } 450 bt_status_t status = 451 sBluetoothHfpInterface->Init(JniHeadsetCallbacks::GetInstance(), 452 max_hf_clients, inband_ringing_enabled); 453 if (status != BT_STATUS_SUCCESS) { 454 ALOGE("%s: Failed to initialize Bluetooth Handsfree Interface, status: %d", 455 __func__, status); 456 sBluetoothHfpInterface = nullptr; 457 return; 458 } 459 460 mCallbacksObj = env->NewGlobalRef(object); 461 } 462 463 static void cleanupNative(JNIEnv* env, jobject object) { 464 std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex); 465 std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex); 466 467 const bt_interface_t* btInf = getBluetoothInterface(); 468 if (!btInf) { 469 ALOGW("%s: Bluetooth module is not loaded", __func__); 470 return; 471 } 472 473 if (sBluetoothHfpInterface) { 474 ALOGI("%s: Cleaning up Bluetooth Handsfree Interface", __func__); 475 sBluetoothHfpInterface->Cleanup(); 476 sBluetoothHfpInterface = nullptr; 477 } 478 479 if (mCallbacksObj) { 480 ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__); 481 env->DeleteGlobalRef(mCallbacksObj); 482 mCallbacksObj = nullptr; 483 } 484 } 485 486 static jboolean connectHfpNative(JNIEnv* env, jobject object, 487 jbyteArray address) { 488 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 489 if (!sBluetoothHfpInterface) { 490 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 491 return JNI_FALSE; 492 } 493 jbyte* addr = env->GetByteArrayElements(address, nullptr); 494 if (!addr) { 495 ALOGE("%s: failed to get device address", __func__); 496 jniThrowIOException(env, EINVAL); 497 return JNI_FALSE; 498 } 499 ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); 500 bt_status_t status = sBluetoothHfpInterface->Connect((RawAddress*)addr); 501 if (status != BT_STATUS_SUCCESS) { 502 ALOGE("Failed HF connection, status: %d", status); 503 } 504 env->ReleaseByteArrayElements(address, addr, 0); 505 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 506 } 507 508 static jboolean disconnectHfpNative(JNIEnv* env, jobject object, 509 jbyteArray address) { 510 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 511 if (!sBluetoothHfpInterface) { 512 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 513 return JNI_FALSE; 514 } 515 jbyte* addr = env->GetByteArrayElements(address, nullptr); 516 if (!addr) { 517 ALOGE("%s: failed to get device address", __func__); 518 jniThrowIOException(env, EINVAL); 519 return JNI_FALSE; 520 } 521 ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); 522 bt_status_t status = sBluetoothHfpInterface->Disconnect((RawAddress*)addr); 523 if (status != BT_STATUS_SUCCESS) { 524 ALOGE("Failed HF disconnection, status: %d", status); 525 } 526 env->ReleaseByteArrayElements(address, addr, 0); 527 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 528 } 529 530 static jboolean connectAudioNative(JNIEnv* env, jobject object, 531 jbyteArray address) { 532 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 533 if (!sBluetoothHfpInterface) { 534 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 535 return JNI_FALSE; 536 } 537 jbyte* addr = env->GetByteArrayElements(address, nullptr); 538 if (!addr) { 539 ALOGE("%s: failed to get device address", __func__); 540 jniThrowIOException(env, EINVAL); 541 return JNI_FALSE; 542 } 543 ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); 544 bt_status_t status = sBluetoothHfpInterface->ConnectAudio((RawAddress*)addr); 545 if (status != BT_STATUS_SUCCESS) { 546 ALOGE("Failed HF audio connection, status: %d", status); 547 } 548 env->ReleaseByteArrayElements(address, addr, 0); 549 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 550 } 551 552 static jboolean disconnectAudioNative(JNIEnv* env, jobject object, 553 jbyteArray address) { 554 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 555 if (!sBluetoothHfpInterface) { 556 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 557 return JNI_FALSE; 558 } 559 jbyte* addr = env->GetByteArrayElements(address, nullptr); 560 if (!addr) { 561 ALOGE("%s: failed to get device address", __func__); 562 jniThrowIOException(env, EINVAL); 563 return JNI_FALSE; 564 } 565 ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); 566 bt_status_t status = 567 sBluetoothHfpInterface->DisconnectAudio((RawAddress*)addr); 568 if (status != BT_STATUS_SUCCESS) { 569 ALOGE("Failed HF audio disconnection, status: %d", status); 570 } 571 env->ReleaseByteArrayElements(address, addr, 0); 572 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 573 } 574 575 static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object, 576 jbyteArray address) { 577 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 578 if (!sBluetoothHfpInterface) { 579 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 580 return JNI_FALSE; 581 } 582 jbyte* addr = env->GetByteArrayElements(address, nullptr); 583 if (!addr) { 584 ALOGE("%s: failed to get device address", __func__); 585 jniThrowIOException(env, EINVAL); 586 return JNI_FALSE; 587 } 588 bt_status_t status = 589 sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr); 590 if (status != BT_STATUS_SUCCESS) { 591 ALOGE("Failed to start voice recognition, status: %d", status); 592 } 593 env->ReleaseByteArrayElements(address, addr, 0); 594 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 595 } 596 597 static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object, 598 jbyteArray address) { 599 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 600 if (!sBluetoothHfpInterface) { 601 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 602 return JNI_FALSE; 603 } 604 jbyte* addr = env->GetByteArrayElements(address, nullptr); 605 if (!addr) { 606 ALOGE("%s: failed to get device address", __func__); 607 jniThrowIOException(env, EINVAL); 608 return JNI_FALSE; 609 } 610 bt_status_t status = 611 sBluetoothHfpInterface->StopVoiceRecognition((RawAddress*)addr); 612 if (status != BT_STATUS_SUCCESS) { 613 ALOGE("Failed to stop voice recognition, status: %d", status); 614 } 615 env->ReleaseByteArrayElements(address, addr, 0); 616 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 617 } 618 619 static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type, 620 jint volume, jbyteArray address) { 621 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 622 if (!sBluetoothHfpInterface) { 623 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 624 return JNI_FALSE; 625 } 626 jbyte* addr = env->GetByteArrayElements(address, nullptr); 627 if (!addr) { 628 ALOGE("%s: failed to get device address", __func__); 629 jniThrowIOException(env, EINVAL); 630 return JNI_FALSE; 631 } 632 bt_status_t status = sBluetoothHfpInterface->VolumeControl( 633 (bluetooth::headset::bthf_volume_type_t)volume_type, volume, 634 (RawAddress*)addr); 635 if (status != BT_STATUS_SUCCESS) { 636 ALOGE("FAILED to control volume, status: %d", status); 637 } 638 env->ReleaseByteArrayElements(address, addr, 0); 639 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 640 } 641 642 static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object, 643 jint network_state, jint service_type, 644 jint signal, jint battery_charge, 645 jbyteArray address) { 646 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 647 if (!sBluetoothHfpInterface) { 648 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 649 return JNI_FALSE; 650 } 651 jbyte* addr = env->GetByteArrayElements(address, nullptr); 652 if (!addr) { 653 ALOGE("%s: failed to get device address", __func__); 654 jniThrowIOException(env, EINVAL); 655 return JNI_FALSE; 656 } 657 bt_status_t status = sBluetoothHfpInterface->DeviceStatusNotification( 658 (bluetooth::headset::bthf_network_state_t)network_state, 659 (bluetooth::headset::bthf_service_type_t)service_type, signal, 660 battery_charge, (RawAddress*)addr); 661 env->ReleaseByteArrayElements(address, addr, 0); 662 if (status != BT_STATUS_SUCCESS) { 663 ALOGE("FAILED to notify device status, status: %d", status); 664 } 665 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 666 } 667 668 static jboolean copsResponseNative(JNIEnv* env, jobject object, 669 jstring operator_str, jbyteArray address) { 670 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 671 if (!sBluetoothHfpInterface) { 672 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 673 return JNI_FALSE; 674 } 675 jbyte* addr = env->GetByteArrayElements(address, nullptr); 676 if (!addr) { 677 ALOGE("%s: failed to get device address", __func__); 678 jniThrowIOException(env, EINVAL); 679 return JNI_FALSE; 680 } 681 const char* operator_name = env->GetStringUTFChars(operator_str, nullptr); 682 bt_status_t status = 683 sBluetoothHfpInterface->CopsResponse(operator_name, (RawAddress*)addr); 684 if (status != BT_STATUS_SUCCESS) { 685 ALOGE("Failed sending cops response, status: %d", status); 686 } 687 env->ReleaseByteArrayElements(address, addr, 0); 688 env->ReleaseStringUTFChars(operator_str, operator_name); 689 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 690 } 691 692 static jboolean cindResponseNative(JNIEnv* env, jobject object, jint service, 693 jint num_active, jint num_held, 694 jint call_state, jint signal, jint roam, 695 jint battery_charge, jbyteArray address) { 696 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 697 if (!sBluetoothHfpInterface) { 698 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 699 return JNI_FALSE; 700 } 701 jbyte* addr = env->GetByteArrayElements(address, nullptr); 702 if (!addr) { 703 ALOGE("%s: failed to get device address", __func__); 704 jniThrowIOException(env, EINVAL); 705 return JNI_FALSE; 706 } 707 bt_status_t status = sBluetoothHfpInterface->CindResponse( 708 service, num_active, num_held, 709 (bluetooth::headset::bthf_call_state_t)call_state, signal, roam, 710 battery_charge, (RawAddress*)addr); 711 if (status != BT_STATUS_SUCCESS) { 712 ALOGE("%s: failed, status: %d", __func__, status); 713 } 714 env->ReleaseByteArrayElements(address, addr, 0); 715 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 716 } 717 718 static jboolean atResponseStringNative(JNIEnv* env, jobject object, 719 jstring response_str, 720 jbyteArray address) { 721 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 722 if (!sBluetoothHfpInterface) { 723 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 724 return JNI_FALSE; 725 } 726 jbyte* addr = env->GetByteArrayElements(address, nullptr); 727 if (!addr) { 728 ALOGE("%s: failed to get device address", __func__); 729 jniThrowIOException(env, EINVAL); 730 return JNI_FALSE; 731 } 732 const char* response = env->GetStringUTFChars(response_str, nullptr); 733 bt_status_t status = 734 sBluetoothHfpInterface->FormattedAtResponse(response, (RawAddress*)addr); 735 if (status != BT_STATUS_SUCCESS) { 736 ALOGE("Failed formatted AT response, status: %d", status); 737 } 738 env->ReleaseByteArrayElements(address, addr, 0); 739 env->ReleaseStringUTFChars(response_str, response); 740 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 741 } 742 743 static jboolean atResponseCodeNative(JNIEnv* env, jobject object, 744 jint response_code, jint cmee_code, 745 jbyteArray address) { 746 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 747 if (!sBluetoothHfpInterface) { 748 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 749 return JNI_FALSE; 750 } 751 jbyte* addr = env->GetByteArrayElements(address, nullptr); 752 if (!addr) { 753 ALOGE("%s: failed to get device address", __func__); 754 jniThrowIOException(env, EINVAL); 755 return JNI_FALSE; 756 } 757 bt_status_t status = sBluetoothHfpInterface->AtResponse( 758 (bluetooth::headset::bthf_at_response_t)response_code, cmee_code, 759 (RawAddress*)addr); 760 if (status != BT_STATUS_SUCCESS) { 761 ALOGE("Failed AT response, status: %d", status); 762 } 763 env->ReleaseByteArrayElements(address, addr, 0); 764 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 765 } 766 767 static jboolean clccResponseNative(JNIEnv* env, jobject object, jint index, 768 jint dir, jint callStatus, jint mode, 769 jboolean mpty, jstring number_str, jint type, 770 jbyteArray address) { 771 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 772 if (!sBluetoothHfpInterface) { 773 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 774 return JNI_FALSE; 775 } 776 jbyte* addr = env->GetByteArrayElements(address, nullptr); 777 if (!addr) { 778 ALOGE("%s: failed to get device address", __func__); 779 jniThrowIOException(env, EINVAL); 780 return JNI_FALSE; 781 } 782 const char* number = nullptr; 783 if (number_str) { 784 number = env->GetStringUTFChars(number_str, nullptr); 785 } 786 bt_status_t status = sBluetoothHfpInterface->ClccResponse( 787 index, (bluetooth::headset::bthf_call_direction_t)dir, 788 (bluetooth::headset::bthf_call_state_t)callStatus, 789 (bluetooth::headset::bthf_call_mode_t)mode, 790 mpty ? bluetooth::headset::BTHF_CALL_MPTY_TYPE_MULTI 791 : bluetooth::headset::BTHF_CALL_MPTY_TYPE_SINGLE, 792 number, (bluetooth::headset::bthf_call_addrtype_t)type, 793 (RawAddress*)addr); 794 if (status != BT_STATUS_SUCCESS) { 795 ALOGE("Failed sending CLCC response, status: %d", status); 796 } 797 env->ReleaseByteArrayElements(address, addr, 0); 798 if (number) { 799 env->ReleaseStringUTFChars(number_str, number); 800 } 801 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 802 } 803 804 static jboolean phoneStateChangeNative(JNIEnv* env, jobject object, 805 jint num_active, jint num_held, 806 jint call_state, jstring number_str, 807 jint type, jbyteArray address) { 808 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 809 if (!sBluetoothHfpInterface) { 810 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 811 return JNI_FALSE; 812 } 813 jbyte* addr = env->GetByteArrayElements(address, nullptr); 814 if (!addr) { 815 ALOGE("%s: failed to get device address", __func__); 816 jniThrowIOException(env, EINVAL); 817 return JNI_FALSE; 818 } 819 const char* number = env->GetStringUTFChars(number_str, nullptr); 820 bt_status_t status = sBluetoothHfpInterface->PhoneStateChange( 821 num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state, 822 number, (bluetooth::headset::bthf_call_addrtype_t)type, 823 (RawAddress*)addr); 824 if (status != BT_STATUS_SUCCESS) { 825 ALOGE("Failed report phone state change, status: %d", status); 826 } 827 env->ReleaseStringUTFChars(number_str, number); 828 env->ReleaseByteArrayElements(address, addr, 0); 829 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 830 } 831 832 static jboolean setScoAllowedNative(JNIEnv* env, jobject object, 833 jboolean value) { 834 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 835 if (!sBluetoothHfpInterface) { 836 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 837 return JNI_FALSE; 838 } 839 bt_status_t status = sBluetoothHfpInterface->SetScoAllowed(value == JNI_TRUE); 840 if (status != BT_STATUS_SUCCESS) { 841 ALOGE("Failed HF set sco allowed, status: %d", status); 842 } 843 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 844 } 845 846 static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value, 847 jbyteArray address) { 848 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 849 if (!sBluetoothHfpInterface) { 850 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 851 return JNI_FALSE; 852 } 853 jbyte* addr = env->GetByteArrayElements(address, NULL); 854 if (!addr) { 855 ALOGE("%s: failed to get device address", __func__); 856 jniThrowIOException(env, EINVAL); 857 return JNI_FALSE; 858 } 859 bt_status_t status = 860 sBluetoothHfpInterface->SendBsir(value == JNI_TRUE, (RawAddress*)addr); 861 if (status != BT_STATUS_SUCCESS) { 862 ALOGE("Failed sending BSIR, value=%d, status=%d", value, status); 863 } 864 env->ReleaseByteArrayElements(address, addr, 0); 865 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 866 } 867 868 static jboolean setActiveDeviceNative(JNIEnv* env, jobject object, 869 jbyteArray address) { 870 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); 871 if (!sBluetoothHfpInterface) { 872 ALOGW("%s: sBluetoothHfpInterface is null", __func__); 873 return JNI_FALSE; 874 } 875 jbyte* addr = env->GetByteArrayElements(address, NULL); 876 if (!addr) { 877 ALOGE("%s: failed to get device address", __func__); 878 jniThrowIOException(env, EINVAL); 879 return JNI_FALSE; 880 } 881 bt_status_t status = 882 sBluetoothHfpInterface->SetActiveDevice((RawAddress*)addr); 883 if (status != BT_STATUS_SUCCESS) { 884 ALOGE("Failed to set active device, status: %d", status); 885 } 886 env->ReleaseByteArrayElements(address, addr, 0); 887 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 888 } 889 890 static JNINativeMethod sMethods[] = { 891 {"classInitNative", "()V", (void*)classInitNative}, 892 {"initializeNative", "(IZ)V", (void*)initializeNative}, 893 {"cleanupNative", "()V", (void*)cleanupNative}, 894 {"connectHfpNative", "([B)Z", (void*)connectHfpNative}, 895 {"disconnectHfpNative", "([B)Z", (void*)disconnectHfpNative}, 896 {"connectAudioNative", "([B)Z", (void*)connectAudioNative}, 897 {"disconnectAudioNative", "([B)Z", (void*)disconnectAudioNative}, 898 {"startVoiceRecognitionNative", "([B)Z", 899 (void*)startVoiceRecognitionNative}, 900 {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative}, 901 {"setVolumeNative", "(II[B)Z", (void*)setVolumeNative}, 902 {"notifyDeviceStatusNative", "(IIII[B)Z", (void*)notifyDeviceStatusNative}, 903 {"copsResponseNative", "(Ljava/lang/String;[B)Z", 904 (void*)copsResponseNative}, 905 {"cindResponseNative", "(IIIIIII[B)Z", (void*)cindResponseNative}, 906 {"atResponseStringNative", "(Ljava/lang/String;[B)Z", 907 (void*)atResponseStringNative}, 908 {"atResponseCodeNative", "(II[B)Z", (void*)atResponseCodeNative}, 909 {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z", 910 (void*)clccResponseNative}, 911 {"phoneStateChangeNative", "(IIILjava/lang/String;I[B)Z", 912 (void*)phoneStateChangeNative}, 913 {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative}, 914 {"sendBsirNative", "(Z[B)Z", (void*)sendBsirNative}, 915 {"setActiveDeviceNative", "([B)Z", (void*)setActiveDeviceNative}, 916 }; 917 918 int register_com_android_bluetooth_hfp(JNIEnv* env) { 919 return jniRegisterNativeMethods( 920 env, "com/android/bluetooth/hfp/HeadsetNativeInterface", sMethods, 921 NELEM(sMethods)); 922 } 923 924 } /* namespace android */ 925