com_android_bluetooth_hfpclient.cpp revision 7d84dc7f7165c69e7d84b50bd21f8a63fa7df275
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#define CHECK_CALLBACK_ENV \ 22 if (!checkCallbackThread()) { \ 23 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\ 24 return; \ 25 } 26 27#include "com_android_bluetooth.h" 28#include "hardware/bt_hf.h" 29#include "utils/Log.h" 30#include "android_runtime/AndroidRuntime.h" 31 32#include <string.h> 33 34namespace android { 35 36static jmethodID method_onConnectionStateChanged; 37static jmethodID method_onAudioStateChanged; 38static jmethodID method_onVrStateChanged; 39static jmethodID method_onAnswerCall; 40static jmethodID method_onHangupCall; 41static jmethodID method_onVolumeChanged; 42static jmethodID method_onDialCall; 43static jmethodID method_onSendDtmf; 44static jmethodID method_onNoiceReductionEnable; 45static jmethodID method_onAtChld; 46static jmethodID method_onAtCnum; 47static jmethodID method_onAtCind; 48static jmethodID method_onAtCops; 49static jmethodID method_onAtClcc; 50static jmethodID method_onUnknownAt; 51static jmethodID method_onKeyPressed; 52 53static const bthf_interface_t *sBluetoothHfpInterface = NULL; 54static jobject mCallbacksObj = NULL; 55static JNIEnv *sCallbackEnv = NULL; 56 57static bool checkCallbackThread() { 58 // Always fetch the latest callbackEnv from AdapterService. 59 // Caching this could cause this sCallbackEnv to go out-of-sync 60 // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event 61 // is received 62 //if (sCallbackEnv == NULL) { 63 sCallbackEnv = getCallbackEnv(); 64 //} 65 JNIEnv* env = AndroidRuntime::getJNIEnv(); 66 if (sCallbackEnv != env || sCallbackEnv == NULL) return false; 67 return true; 68} 69 70static void connection_state_callback(bthf_connection_state_t state, bt_bdaddr_t* bd_addr) { 71 jbyteArray addr; 72 73 ALOGI("%s", __FUNCTION__); 74 75 CHECK_CALLBACK_ENV 76 addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 77 if (!addr) { 78 ALOGE("Fail to new jbyteArray bd addr for connection state"); 79 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 80 return; 81 } 82 83 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); 84 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, 85 (jint) state, addr); 86 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 87 sCallbackEnv->DeleteLocalRef(addr); 88} 89 90static void audio_state_callback(bthf_audio_state_t state, bt_bdaddr_t* bd_addr) { 91 jbyteArray addr; 92 93 CHECK_CALLBACK_ENV 94 addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 95 if (!addr) { 96 ALOGE("Fail to new jbyteArray bd addr for audio state"); 97 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 98 return; 99 } 100 101 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr); 102 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, (jint) state, addr); 103 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 104 sCallbackEnv->DeleteLocalRef(addr); 105} 106 107static void voice_recognition_callback(bthf_vr_state_t state) { 108 CHECK_CALLBACK_ENV 109 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint) state); 110 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 111} 112 113static void answer_call_callback() { 114 CHECK_CALLBACK_ENV 115 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall); 116 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 117} 118 119static void hangup_call_callback() { 120 CHECK_CALLBACK_ENV 121 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHangupCall); 122 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 123} 124 125static void volume_control_callback(bthf_volume_type_t type, int volume) { 126 CHECK_CALLBACK_ENV 127 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChanged, (jint) type, (jint) volume); 128 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 129} 130 131static void dial_call_callback(char *number) { 132 CHECK_CALLBACK_ENV 133 jstring js_number = sCallbackEnv->NewStringUTF(number); 134 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDialCall, 135 js_number); 136 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 137 sCallbackEnv->DeleteLocalRef(js_number); 138} 139 140static void dtmf_cmd_callback(char dtmf) { 141 CHECK_CALLBACK_ENV 142 // TBD dtmf has changed from int to char 143 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf); 144 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 145} 146 147static void noice_reduction_callback(bthf_nrec_t nrec) { 148 CHECK_CALLBACK_ENV 149 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiceReductionEnable, 150 nrec == BTHF_NREC_START); 151 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 152} 153 154static void at_chld_callback(bthf_chld_type_t chld) { 155 CHECK_CALLBACK_ENV 156 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld); 157 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 158} 159 160static void at_cnum_callback() { 161 CHECK_CALLBACK_ENV 162 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum); 163 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 164} 165 166static void at_cind_callback() { 167 CHECK_CALLBACK_ENV 168 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind); 169 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 170} 171 172static void at_cops_callback() { 173 CHECK_CALLBACK_ENV 174 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops); 175 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 176} 177 178static void at_clcc_callback() { 179 CHECK_CALLBACK_ENV 180 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc); 181 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 182} 183 184static void unknown_at_callback(char *at_string) { 185 CHECK_CALLBACK_ENV 186 jstring js_at_string = sCallbackEnv->NewStringUTF(at_string); 187 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownAt, 188 js_at_string); 189 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 190 sCallbackEnv->DeleteLocalRef(js_at_string); 191} 192 193static void key_pressed_callback() { 194 CHECK_CALLBACK_ENV 195 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed); 196 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 197} 198 199static bthf_callbacks_t sBluetoothHfpCallbacks = { 200 sizeof(sBluetoothHfpCallbacks), 201 connection_state_callback, 202 audio_state_callback, 203 voice_recognition_callback, 204 answer_call_callback, 205 hangup_call_callback, 206 volume_control_callback, 207 dial_call_callback, 208 dtmf_cmd_callback, 209 noice_reduction_callback, 210 at_chld_callback, 211 at_cnum_callback, 212 at_cind_callback, 213 at_cops_callback, 214 at_clcc_callback, 215 unknown_at_callback, 216 key_pressed_callback 217}; 218 219static void classInitNative(JNIEnv* env, jclass clazz) { 220 int err; 221 /* 222 const bt_interface_t* btInf; 223 bt_status_t status; 224 */ 225 226 method_onConnectionStateChanged = 227 env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V"); 228 method_onAudioStateChanged = env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V"); 229 method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I)V"); 230 method_onAnswerCall = env->GetMethodID(clazz, "onAnswerCall", "()V"); 231 method_onHangupCall = env->GetMethodID(clazz, "onHangupCall", "()V"); 232 method_onVolumeChanged = env->GetMethodID(clazz, "onVolumeChanged", "(II)V"); 233 method_onDialCall = env->GetMethodID(clazz, "onDialCall", "(Ljava/lang/String;)V"); 234 method_onSendDtmf = env->GetMethodID(clazz, "onSendDtmf", "(I)V"); 235 method_onNoiceReductionEnable = env->GetMethodID(clazz, "onNoiceReductionEnable", "(Z)V"); 236 method_onAtChld = env->GetMethodID(clazz, "onAtChld", "(I)V"); 237 method_onAtCnum = env->GetMethodID(clazz, "onAtCnum", "()V"); 238 method_onAtCind = env->GetMethodID(clazz, "onAtCind", "()V"); 239 method_onAtCops = env->GetMethodID(clazz, "onAtCops", "()V"); 240 method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "()V"); 241 method_onUnknownAt = env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;)V"); 242 method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "()V"); 243 244 /* 245 if ( (btInf = getBluetoothInterface()) == NULL) { 246 ALOGE("Bluetooth module is not loaded"); 247 return; 248 } 249 250 if ( (sBluetoothHfpInterface = (bthf_interface_t *) 251 btInf->get_profile_interface(BT_PROFILE_HANDSFREE_ID)) == NULL) { 252 ALOGE("Failed to get Bluetooth Handsfree Interface"); 253 return; 254 } 255 256 // TODO(BT) do this only once or 257 // Do we need to do this every time the BT reenables? 258 if ( (status = sBluetoothHfpInterface->init(&sBluetoothHfpCallbacks)) != BT_STATUS_SUCCESS) { 259 ALOGE("Failed to initialize Bluetooth HFP, status: %d", status); 260 sBluetoothHfpInterface = NULL; 261 return; 262 } 263 */ 264 265 ALOGI("%s: succeeds", __FUNCTION__); 266} 267 268static void initializeNative(JNIEnv *env, jobject object) { 269 const bt_interface_t* btInf; 270 bt_status_t status; 271 272 if ( (btInf = getBluetoothInterface()) == NULL) { 273 ALOGE("Bluetooth module is not loaded"); 274 return; 275 } 276 277 if (sBluetoothHfpInterface !=NULL) { 278 ALOGW("Cleaning up Bluetooth Handsfree Interface before initializing..."); 279 sBluetoothHfpInterface->cleanup(); 280 sBluetoothHfpInterface = NULL; 281 } 282 283 if (mCallbacksObj != NULL) { 284 ALOGW("Cleaning up Bluetooth Handsfree callback object"); 285 env->DeleteGlobalRef(mCallbacksObj); 286 mCallbacksObj = NULL; 287 } 288 289 if ( (sBluetoothHfpInterface = (bthf_interface_t *) 290 btInf->get_profile_interface(BT_PROFILE_HANDSFREE_ID)) == NULL) { 291 ALOGE("Failed to get Bluetooth Handsfree Interface"); 292 return; 293 } 294 295 if ( (status = sBluetoothHfpInterface->init(&sBluetoothHfpCallbacks)) != BT_STATUS_SUCCESS) { 296 ALOGE("Failed to initialize Bluetooth HFP, status: %d", status); 297 sBluetoothHfpInterface = NULL; 298 return; 299 } 300 301 mCallbacksObj = env->NewGlobalRef(object); 302} 303 304static void cleanupNative(JNIEnv *env, jobject object) { 305 const bt_interface_t* btInf; 306 bt_status_t status; 307 308 if ( (btInf = getBluetoothInterface()) == NULL) { 309 ALOGE("Bluetooth module is not loaded"); 310 return; 311 } 312 313 if (sBluetoothHfpInterface !=NULL) { 314 ALOGW("Cleaning up Bluetooth Handsfree Interface..."); 315 sBluetoothHfpInterface->cleanup(); 316 sBluetoothHfpInterface = NULL; 317 } 318 319 if (mCallbacksObj != NULL) { 320 ALOGW("Cleaning up Bluetooth Handsfree callback object"); 321 env->DeleteGlobalRef(mCallbacksObj); 322 mCallbacksObj = NULL; 323 } 324} 325 326static jboolean connectHfpNative(JNIEnv *env, jobject object, jbyteArray address) { 327 jbyte *addr; 328 bt_status_t status; 329 330 ALOGI("%s: sBluetoothHfpInterface: %p", __FUNCTION__, sBluetoothHfpInterface); 331 if (!sBluetoothHfpInterface) return JNI_FALSE; 332 333 addr = env->GetByteArrayElements(address, NULL); 334 if (!addr) { 335 jniThrowIOException(env, EINVAL); 336 return JNI_FALSE; 337 } 338 339 if ((status = sBluetoothHfpInterface->connect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) { 340 ALOGE("Failed HF connection, status: %d", status); 341 } 342 env->ReleaseByteArrayElements(address, addr, 0); 343 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 344} 345 346static jboolean disconnectHfpNative(JNIEnv *env, jobject object, jbyteArray address) { 347 jbyte *addr; 348 bt_status_t status; 349 350 if (!sBluetoothHfpInterface) return JNI_FALSE; 351 352 addr = env->GetByteArrayElements(address, NULL); 353 if (!addr) { 354 jniThrowIOException(env, EINVAL); 355 return JNI_FALSE; 356 } 357 358 if ( (status = sBluetoothHfpInterface->disconnect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) { 359 ALOGE("Failed HF disconnection, status: %d", status); 360 } 361 env->ReleaseByteArrayElements(address, addr, 0); 362 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 363} 364 365static jboolean connectAudioNative(JNIEnv *env, jobject object, jbyteArray address) { 366 jbyte *addr; 367 bt_status_t status; 368 369 if (!sBluetoothHfpInterface) return JNI_FALSE; 370 371 addr = env->GetByteArrayElements(address, NULL); 372 if (!addr) { 373 jniThrowIOException(env, EINVAL); 374 return JNI_FALSE; 375 } 376 377 if ( (status = sBluetoothHfpInterface->connect_audio((bt_bdaddr_t *)addr)) != 378 BT_STATUS_SUCCESS) { 379 ALOGE("Failed HF audio connection, status: %d", status); 380 } 381 env->ReleaseByteArrayElements(address, addr, 0); 382 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 383} 384 385static jboolean disconnectAudioNative(JNIEnv *env, jobject object, jbyteArray address) { 386 jbyte *addr; 387 bt_status_t status; 388 389 if (!sBluetoothHfpInterface) return JNI_FALSE; 390 391 addr = env->GetByteArrayElements(address, NULL); 392 if (!addr) { 393 jniThrowIOException(env, EINVAL); 394 return JNI_FALSE; 395 } 396 397 if ( (status = sBluetoothHfpInterface->disconnect_audio((bt_bdaddr_t *) addr)) != 398 BT_STATUS_SUCCESS) { 399 ALOGE("Failed HF audio disconnection, status: %d", status); 400 } 401 env->ReleaseByteArrayElements(address, addr, 0); 402 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 403} 404 405static jboolean startVoiceRecognitionNative(JNIEnv *env, jobject object) { 406 bt_status_t status; 407 if (!sBluetoothHfpInterface) return JNI_FALSE; 408 409 if ( (status = sBluetoothHfpInterface->start_voice_recognition()) != BT_STATUS_SUCCESS) { 410 ALOGE("Failed to start voice recognition, status: %d", status); 411 } 412 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 413} 414 415static jboolean stopVoiceRecognitionNative(JNIEnv *env, jobject object) { 416 bt_status_t status; 417 if (!sBluetoothHfpInterface) return JNI_FALSE; 418 419 if ( (status = sBluetoothHfpInterface->stop_voice_recognition()) != BT_STATUS_SUCCESS) { 420 ALOGE("Failed to stop voice recognition, status: %d", status); 421 } 422 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 423} 424 425static jboolean setVolumeNative(JNIEnv *env, jobject object, jint volume_type, jint volume) { 426 bt_status_t status; 427 if (!sBluetoothHfpInterface) return JNI_FALSE; 428 429 if ( (status = sBluetoothHfpInterface->volume_control((bthf_volume_type_t) volume_type, 430 volume)) != BT_STATUS_SUCCESS) { 431 ALOGE("FAILED to control volume, status: %d", status); 432 } 433 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 434} 435 436static jboolean notifyDeviceStatusNative(JNIEnv *env, jobject object, 437 jint network_state, jint service_type, jint signal, 438 jint battery_charge) { 439 bt_status_t status; 440 if (!sBluetoothHfpInterface) return JNI_FALSE; 441 442 if ( (status = sBluetoothHfpInterface->device_status_notification 443 ((bthf_network_state_t) network_state, (bthf_service_type_t) service_type, 444 signal, battery_charge)) != BT_STATUS_SUCCESS) { 445 ALOGE("FAILED to notify device status, status: %d", status); 446 } 447 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 448} 449 450static jboolean copsResponseNative(JNIEnv *env, jobject object, jstring operator_str) { 451 bt_status_t status; 452 const char *operator_name; 453 if (!sBluetoothHfpInterface) return JNI_FALSE; 454 455 operator_name = env->GetStringUTFChars(operator_str, NULL); 456 457 if ( (status = sBluetoothHfpInterface->cops_response(operator_name)) != BT_STATUS_SUCCESS) { 458 ALOGE("Failed sending cops response, status: %d", status); 459 } 460 env->ReleaseStringUTFChars(operator_str, operator_name); 461 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 462} 463 464static jboolean cindResponseNative(JNIEnv *env, jobject object, 465 jint service, jint num_active, jint num_held, jint call_state, 466 jint signal, jint roam, jint battery_charge) { 467 bt_status_t status; 468 if (!sBluetoothHfpInterface) return JNI_FALSE; 469 470 if ( (status = sBluetoothHfpInterface->cind_response(service, num_active, num_held, 471 (bthf_call_state_t) call_state, 472 signal, roam, battery_charge)) != BT_STATUS_SUCCESS) { 473 ALOGE("Failed cind_response, status: %d", status); 474 } 475 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 476} 477 478 479static jboolean atResponseStringNative(JNIEnv *env, jobject object, jstring response_str) { 480 bt_status_t status; 481 const char *response; 482 if (!sBluetoothHfpInterface) return JNI_FALSE; 483 484 response = env->GetStringUTFChars(response_str, NULL); 485 486 if ( (status = sBluetoothHfpInterface->formatted_at_response(response)) != BT_STATUS_SUCCESS) { 487 ALOGE("Failed formatted AT response, status: %d", status); 488 } 489 env->ReleaseStringUTFChars(response_str, response); 490 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 491} 492 493static jboolean atResponseCodeNative(JNIEnv *env, jobject object, jint response_code, jint cmee_code) { 494 bt_status_t status; 495 if (!sBluetoothHfpInterface) return JNI_FALSE; 496 497 if ( (status = sBluetoothHfpInterface->at_response((bthf_at_response_t) response_code, cmee_code)) != 498 BT_STATUS_SUCCESS) { 499 ALOGE("Failed AT response, status: %d", status); 500 } 501 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 502} 503 504static jboolean clccResponseNative(JNIEnv *env, jobject object, jint index, jint dir, 505 jint callStatus, jint mode, jboolean mpty, jstring number_str, 506 jint type) { 507 bt_status_t status; 508 const char *number = NULL; 509 if (!sBluetoothHfpInterface) return JNI_FALSE; 510 511 if (number_str) 512 number = env->GetStringUTFChars(number_str, NULL); 513 514 if ( (status = sBluetoothHfpInterface->clcc_response(index, (bthf_call_direction_t) dir, 515 (bthf_call_state_t) callStatus, (bthf_call_mode_t) mode, 516 mpty ? BTHF_CALL_MPTY_TYPE_MULTI : BTHF_CALL_MPTY_TYPE_SINGLE, 517 number, (bthf_call_addrtype_t) type)) != BT_STATUS_SUCCESS) { 518 ALOGE("Failed sending CLCC response, status: %d", status); 519 } 520 if (number) 521 env->ReleaseStringUTFChars(number_str, number); 522 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 523} 524 525static jboolean phoneStateChangeNative(JNIEnv *env, jobject object, jint num_active, jint num_held, 526 jint call_state, jstring number_str, jint type) { 527 bt_status_t status; 528 const char *number; 529 if (!sBluetoothHfpInterface) return JNI_FALSE; 530 531 number = env->GetStringUTFChars(number_str, NULL); 532 533 if ( (status = sBluetoothHfpInterface->phone_state_change(num_active, num_held, 534 (bthf_call_state_t) call_state, number, 535 (bthf_call_addrtype_t) type)) != BT_STATUS_SUCCESS) { 536 ALOGE("Failed report phone state change, status: %d", status); 537 } 538 env->ReleaseStringUTFChars(number_str, number); 539 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 540} 541 542static JNINativeMethod sMethods[] = { 543 {"classInitNative", "()V", (void *) classInitNative}, 544 {"initializeNative", "()V", (void *) initializeNative}, 545 {"cleanupNative", "()V", (void *) cleanupNative}, 546 {"connectHfpNative", "([B)Z", (void *) connectHfpNative}, 547 {"disconnectHfpNative", "([B)Z", (void *) disconnectHfpNative}, 548 {"connectAudioNative", "([B)Z", (void *) connectAudioNative}, 549 {"disconnectAudioNative", "([B)Z", (void *) disconnectAudioNative}, 550 {"startVoiceRecognitionNative", "()Z", (void *) startVoiceRecognitionNative}, 551 {"stopVoiceRecognitionNative", "()Z", (void *) stopVoiceRecognitionNative}, 552 {"setVolumeNative", "(II)Z", (void *) setVolumeNative}, 553 {"notifyDeviceStatusNative", "(IIII)Z", (void *) notifyDeviceStatusNative}, 554 {"copsResponseNative", "(Ljava/lang/String;)Z", (void *) copsResponseNative}, 555 {"cindResponseNative", "(IIIIIII)Z", (void *) cindResponseNative}, 556 {"atResponseStringNative", "(Ljava/lang/String;)Z", (void *) atResponseStringNative}, 557 {"atResponseCodeNative", "(II)Z", (void *)atResponseCodeNative}, 558 {"clccResponseNative", "(IIIIZLjava/lang/String;I)Z", (void *) clccResponseNative}, 559 {"phoneStateChangeNative", "(IIILjava/lang/String;I)Z", (void *) phoneStateChangeNative}, 560}; 561 562int register_com_android_bluetooth_hfp(JNIEnv* env) 563{ 564 return jniRegisterNativeMethods(env, "com/android/bluetooth/hfp/HeadsetStateMachine", 565 sMethods, NELEM(sMethods)); 566} 567 568} /* namespace android */ 569