16c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie/*
2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project
3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License");
5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License.
6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at
7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *      http://www.apache.org/licenses/LICENSE-2.0
9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software
11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS,
12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and
14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License.
156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie */
166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define LOG_TAG "BluetoothHeadsetServiceJni"
186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define LOG_NDEBUG 0
206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define CHECK_CALLBACK_ENV                                                      \
226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if (!checkCallbackThread()) {                                                \
23c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie       return;                                                                  \
256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "com_android_bluetooth.h"
286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "hardware/bt_hf.h"
296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "utils/Log.h"
306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "android_runtime/AndroidRuntime.h"
316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include <string.h>
336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xienamespace android {
356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onConnectionStateChanged;
376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAudioStateChanged;
386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onVrStateChanged;
396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAnswerCall;
406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onHangupCall;
416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onVolumeChanged;
426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onDialCall;
436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onSendDtmf;
446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onNoiceReductionEnable;
45b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xiestatic jmethodID method_onWBS;
466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtChld;
476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtCnum;
486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtCind;
496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtCops;
506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtClcc;
516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onUnknownAt;
526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onKeyPressed;
536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic const bthf_interface_t *sBluetoothHfpInterface = NULL;
556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jobject mCallbacksObj = NULL;
566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic JNIEnv *sCallbackEnv = NULL;
576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic bool checkCallbackThread() {
5993f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    // Always fetch the latest callbackEnv from AdapterService.
6093f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    // Caching this could cause this sCallbackEnv to go out-of-sync
6193f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
6293f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    // is received
6393f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    //if (sCallbackEnv == NULL) {
6493f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    sCallbackEnv = getCallbackEnv();
6593f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    //}
666c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    JNIEnv* env = AndroidRuntime::getJNIEnv();
676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return true;
696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
71b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xiestatic jbyteArray marshall_bda(bt_bdaddr_t* bd_addr)
72b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie{
73b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    jbyteArray addr;
74b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
75b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if (!addr) {
76b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        ALOGE("Fail to new jbyteArray bd addr");
77b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
78b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        return NULL;
79b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    }
80b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
81b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    return addr;
82b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie}
83b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic void connection_state_callback(bthf_connection_state_t state, bt_bdaddr_t* bd_addr) {
856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyteArray addr;
866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
87c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGI("%s", __FUNCTION__);
886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
92c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Fail to new jbyteArray bd addr for connection state");
936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return;
956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
966c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged,
996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                 (jint) state, addr);
1006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
1016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->DeleteLocalRef(addr);
1026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1036c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic void audio_state_callback(bthf_audio_state_t state, bt_bdaddr_t* bd_addr) {
1056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyteArray addr;
1066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
1086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
1096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
110c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Fail to new jbyteArray bd addr for audio state");
1116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
1126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return;
1136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
1166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, (jint) state, addr);
1176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
1186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->DeleteLocalRef(addr);
1196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
12169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void voice_recognition_callback(bthf_vr_state_t state, bt_bdaddr_t* bd_addr) {
12269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
12369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
12569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
12669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
12769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
12869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
12969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
13069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
13169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
13269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
13369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint) state, addr);
1346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
13569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
1366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
13869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void answer_call_callback(bt_bdaddr_t* bd_addr) {
13969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
14069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
14269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
14369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
14469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
14569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
14669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
14769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
14869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
14969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
15069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall, addr);
1516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
15269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
1536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
15569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void hangup_call_callback(bt_bdaddr_t* bd_addr) {
15669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
15769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
15969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
16069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
16169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
16269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
16369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
16469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
16569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
16669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
16769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHangupCall, addr);
1686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
16969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
1706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
17269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void volume_control_callback(bthf_volume_type_t type, int volume, bt_bdaddr_t* bd_addr) {
17369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
17469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
17669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
17769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
17869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
17969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
18069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
18169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
18269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
18369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
18469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChanged, (jint) type,
18569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                                  (jint) volume, addr);
1866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
18769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
1886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
19069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void dial_call_callback(char *number, bt_bdaddr_t* bd_addr) {
19169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
19269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
19469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
19569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
19669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
19769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
19869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
19969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
20069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
20169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
202976912e5f597f015754aa67f2a74040e27f58eabSyed Ibrahim M    jstring js_number = sCallbackEnv->NewStringUTF(number);
2036c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDialCall,
20469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                 js_number, addr);
2056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
206976912e5f597f015754aa67f2a74040e27f58eabSyed Ibrahim M    sCallbackEnv->DeleteLocalRef(js_number);
20769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
21069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void dtmf_cmd_callback(char dtmf, bt_bdaddr_t* bd_addr) {
21169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
21269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
21469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
21569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
21669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
21769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
21869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
21969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
22069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
22169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
2226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // TBD dtmf has changed from int to char
22369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf, addr);
2246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
22569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
22869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void noice_reduction_callback(bthf_nrec_t nrec, bt_bdaddr_t* bd_addr) {
22969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
23069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
23269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
23369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
23469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
23569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
23669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
23769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
23869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
2396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiceReductionEnable,
24069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                 nrec == BTHF_NREC_START, addr);
2416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
24269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
245b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xiestatic void wbs_callback(bthf_wbs_config_t wbs_config, bt_bdaddr_t* bd_addr) {
246b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    jbyteArray addr;
247b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
248b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    CHECK_CALLBACK_ENV
249b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
250b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if ((addr = marshall_bda(bd_addr)) == NULL)
251b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        return;
252b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
253b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWBS, wbs_config, addr);
254b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
255b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    sCallbackEnv->DeleteLocalRef(addr);
256b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie}
257b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
25869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_chld_callback(bthf_chld_type_t chld, bt_bdaddr_t* bd_addr) {
25969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
26069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
26269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
26369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
26469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
26569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
26669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
26769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
26869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
26969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
27069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld, addr);
2716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
27269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
27569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_cnum_callback(bt_bdaddr_t* bd_addr) {
27669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
27769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
27969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
28069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
28169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
28269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
28369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
28469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
28569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
28669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
28769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum, addr);
2886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
28969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
29269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_cind_callback(bt_bdaddr_t* bd_addr) {
29369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
29469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
29669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
29769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
29869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
29969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
30069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
30169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
30269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
30369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
30469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind, addr);
3056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
30669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
30969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_cops_callback(bt_bdaddr_t* bd_addr) {
31069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
31169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
3126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
31369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
31469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
31569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
31669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
31769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
31869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
31969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
32069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
32169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops, addr);
3226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
32369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
32669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_clcc_callback(bt_bdaddr_t* bd_addr) {
32769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
32869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
3296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
33069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
33169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
33269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
33369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
33469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
33569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
33669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
33769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
33869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc, addr);
3396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
34069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
34369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void unknown_at_callback(char *at_string, bt_bdaddr_t* bd_addr) {
34469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
34569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
3466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
34769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
34869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
34969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
35069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
35169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
35269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
35369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
35469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
355976912e5f597f015754aa67f2a74040e27f58eabSyed Ibrahim M    jstring js_at_string = sCallbackEnv->NewStringUTF(at_string);
3566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownAt,
35769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                 js_at_string, addr);
3586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
359976912e5f597f015754aa67f2a74040e27f58eabSyed Ibrahim M    sCallbackEnv->DeleteLocalRef(js_at_string);
36069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3626c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
36369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void key_pressed_callback(bt_bdaddr_t* bd_addr) {
36469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
36569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
3666c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
36769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
36869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
36969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
37069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
37169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
37269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
37369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
37469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
37569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed, addr);
3766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
37769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
3806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic bthf_callbacks_t sBluetoothHfpCallbacks = {
3816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sizeof(sBluetoothHfpCallbacks),
3826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    connection_state_callback,
3836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    audio_state_callback,
3846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    voice_recognition_callback,
3856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    answer_call_callback,
3866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    hangup_call_callback,
3876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    volume_control_callback,
3886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    dial_call_callback,
3896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    dtmf_cmd_callback,
3906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    noice_reduction_callback,
391b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    wbs_callback,
3926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_chld_callback,
3936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_cnum_callback,
3946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_cind_callback,
3956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_cops_callback,
3966c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_clcc_callback,
3976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    unknown_at_callback,
3986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    key_pressed_callback
3996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie};
4006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
4016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic void classInitNative(JNIEnv* env, jclass clazz) {
4026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int err;
4036654f5c903de510a70f9e72cd5ad7837b615d93ffredc    /*
4046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    const bt_interface_t* btInf;
4056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
4066654f5c903de510a70f9e72cd5ad7837b615d93ffredc    */
4076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
4086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    method_onConnectionStateChanged =
4096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
4106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    method_onAudioStateChanged = env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V");
41169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V");
41269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAnswerCall = env->GetMethodID(clazz, "onAnswerCall", "([B)V");
41369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onHangupCall = env->GetMethodID(clazz, "onHangupCall", "([B)V");
41469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onVolumeChanged = env->GetMethodID(clazz, "onVolumeChanged", "(II[B)V");
41569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onDialCall = env->GetMethodID(clazz, "onDialCall", "(Ljava/lang/String;[B)V");
41669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onSendDtmf = env->GetMethodID(clazz, "onSendDtmf", "(I[B)V");
41769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onNoiceReductionEnable = env->GetMethodID(clazz, "onNoiceReductionEnable", "(Z[B)V");
418b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    method_onWBS = env->GetMethodID(clazz,"onWBS","(I[B)V");
41969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtChld = env->GetMethodID(clazz, "onAtChld", "(I[B)V");
42069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtCnum = env->GetMethodID(clazz, "onAtCnum", "([B)V");
42169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtCind = env->GetMethodID(clazz, "onAtCind", "([B)V");
42269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtCops = env->GetMethodID(clazz, "onAtCops", "([B)V");
42369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "([B)V");
42469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onUnknownAt = env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;[B)V");
42569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "([B)V");
4266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
4276654f5c903de510a70f9e72cd5ad7837b615d93ffredc    /*
4286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (btInf = getBluetoothInterface()) == NULL) {
429c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Bluetooth module is not loaded");
4306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return;
4316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
4326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
4336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (sBluetoothHfpInterface = (bthf_interface_t *)
4346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie          btInf->get_profile_interface(BT_PROFILE_HANDSFREE_ID)) == NULL) {
435c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed to get Bluetooth Handsfree Interface");
4366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return;
4376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
4386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
4396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // TODO(BT) do this only once or
4406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    //          Do we need to do this every time the BT reenables?
4416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->init(&sBluetoothHfpCallbacks)) != BT_STATUS_SUCCESS) {
442c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed to initialize Bluetooth HFP, status: %d", status);
4436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        sBluetoothHfpInterface = NULL;
4446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return;
4456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
4466654f5c903de510a70f9e72cd5ad7837b615d93ffredc    */
4476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
448c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGI("%s: succeeds", __FUNCTION__);
4496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
4506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
45169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void initializeNative(JNIEnv *env, jobject object, jint max_hf_clients) {
4526654f5c903de510a70f9e72cd5ad7837b615d93ffredc    const bt_interface_t* btInf;
4536654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
4546654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4556654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (btInf = getBluetoothInterface()) == NULL) {
456e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth module is not loaded");
4576654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
4586654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4596654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4606654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sBluetoothHfpInterface !=NULL) {
461e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth Handsfree Interface before initializing...");
4626654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface->cleanup();
4636654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface = NULL;
4646654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4656654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4666654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
467e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth Handsfree callback object");
4686654f5c903de510a70f9e72cd5ad7837b615d93ffredc        env->DeleteGlobalRef(mCallbacksObj);
4696654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mCallbacksObj = NULL;
4706654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4716654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4726654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (sBluetoothHfpInterface = (bthf_interface_t *)
4736654f5c903de510a70f9e72cd5ad7837b615d93ffredc          btInf->get_profile_interface(BT_PROFILE_HANDSFREE_ID)) == NULL) {
474e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed to get Bluetooth Handsfree Interface");
4756654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
4766654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4776654f5c903de510a70f9e72cd5ad7837b615d93ffredc
47869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->init(&sBluetoothHfpCallbacks,
47969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava          max_hf_clients)) != BT_STATUS_SUCCESS) {
480e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed to initialize Bluetooth HFP, status: %d", status);
4816654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface = NULL;
4826654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
4836654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4846654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    mCallbacksObj = env->NewGlobalRef(object);
4866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
4876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
4886654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void cleanupNative(JNIEnv *env, jobject object) {
4896654f5c903de510a70f9e72cd5ad7837b615d93ffredc    const bt_interface_t* btInf;
4906654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
4916654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4926654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (btInf = getBluetoothInterface()) == NULL) {
493e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth module is not loaded");
4946654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
4956654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4966654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4976654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sBluetoothHfpInterface !=NULL) {
498e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth Handsfree Interface...");
4996654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface->cleanup();
5006654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface = NULL;
5016654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5026654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5036654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
504e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth Handsfree callback object");
5056654f5c903de510a70f9e72cd5ad7837b615d93ffredc        env->DeleteGlobalRef(mCallbacksObj);
5066654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mCallbacksObj = NULL;
5076654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5086654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
5096654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean connectHfpNative(JNIEnv *env, jobject object, jbyteArray address) {
5116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyte *addr;
5126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
514c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGI("%s: sBluetoothHfpInterface: %p", __FUNCTION__, sBluetoothHfpInterface);
5156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
5186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
5196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        jniThrowIOException(env, EINVAL);
5206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return JNI_FALSE;
5216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ((status = sBluetoothHfpInterface->connect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
524c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed HF connection, status: %d", status);
5256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
5276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
5286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
5296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean disconnectHfpNative(JNIEnv *env, jobject object, jbyteArray address) {
5316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyte *addr;
5326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
5376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
5386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        jniThrowIOException(env, EINVAL);
5396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return JNI_FALSE;
5406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->disconnect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
543c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed HF disconnection, status: %d", status);
5446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
5466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
5476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
5486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean connectAudioNative(JNIEnv *env, jobject object, jbyteArray address) {
5506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyte *addr;
5516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
5566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
5576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        jniThrowIOException(env, EINVAL);
5586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return JNI_FALSE;
5596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->connect_audio((bt_bdaddr_t *)addr)) !=
5626c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         BT_STATUS_SUCCESS) {
563c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed HF audio connection, status: %d", status);
5646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
5666c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
5676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
5686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean disconnectAudioNative(JNIEnv *env, jobject object, jbyteArray address) {
5706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyte *addr;
5716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
5766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
5776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        jniThrowIOException(env, EINVAL);
5786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return JNI_FALSE;
5796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->disconnect_audio((bt_bdaddr_t *) addr)) !=
5826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         BT_STATUS_SUCCESS) {
583c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed HF audio disconnection, status: %d", status);
5846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
5866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
5876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
5886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
58969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean startVoiceRecognitionNative(JNIEnv *env, jobject object, jbyteArray address) {
59069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
5916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
59469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
59569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
59669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
59769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
59869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
59969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
60069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->start_voice_recognition((bt_bdaddr_t *) addr))
60169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                          != BT_STATUS_SUCCESS) {
602c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed to start voice recognition, status: %d", status);
6036c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
60469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
6056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
60869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean stopVoiceRecognitionNative(JNIEnv *env, jobject object, jbyteArray address) {
60969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
6106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
6116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
61369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
61469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
61569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
61669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
61769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
61869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
61969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->stop_voice_recognition((bt_bdaddr_t *) addr))
62069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                     != BT_STATUS_SUCCESS) {
621c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed to stop voice recognition, status: %d", status);
6226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
62369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
6246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
62769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean setVolumeNative(JNIEnv *env, jobject object, jint volume_type,
62869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                     jint volume, jbyteArray address) {
62969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
6306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
6316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
63369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
63469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
63569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
63669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
63769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
63869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
6396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->volume_control((bthf_volume_type_t) volume_type,
64069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                volume, (bt_bdaddr_t *) addr)) != BT_STATUS_SUCCESS) {
641c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("FAILED to control volume, status: %d", status);
6426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
64369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
6446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
6476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean notifyDeviceStatusNative(JNIEnv *env, jobject object,
6486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                         jint network_state, jint service_type, jint signal,
6496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                         jint battery_charge) {
6506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
6516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
6536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->device_status_notification
6546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie          ((bthf_network_state_t) network_state, (bthf_service_type_t) service_type,
6556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie           signal, battery_charge)) != BT_STATUS_SUCCESS) {
656c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("FAILED to notify device status, status: %d", status);
6576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
6586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
66169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean copsResponseNative(JNIEnv *env, jobject object, jstring operator_str,
66269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                              jbyteArray address) {
66369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
6646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
6656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    const char *operator_name;
6666c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
66869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
66969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
67069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
67169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
67269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
67369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
6746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    operator_name = env->GetStringUTFChars(operator_str, NULL);
6756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
67669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->cops_response(operator_name,(bt_bdaddr_t *) addr))
67769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                                  != BT_STATUS_SUCCESS) {
678c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed sending cops response, status: %d", status);
6796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
68069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
6816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseStringUTFChars(operator_str, operator_name);
6826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
6856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean cindResponseNative(JNIEnv *env, jobject object,
6866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                   jint service, jint num_active, jint num_held, jint call_state,
68769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                   jint signal, jint roam, jint battery_charge, jbyteArray address) {
68869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
6896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
69069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
69169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    ALOGI("%s: sBluetoothHfpInterface: %p", __FUNCTION__, sBluetoothHfpInterface);
6926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
69469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
69569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
69669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
69769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
69869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
69969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
7006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->cind_response(service, num_active, num_held,
7016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                       (bthf_call_state_t) call_state,
70269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                       signal, roam, battery_charge, (bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
703c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed cind_response, status: %d", status);
7046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
70569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
7066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
7076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
7086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
7096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
71069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean atResponseStringNative(JNIEnv *env, jobject object, jstring response_str,
71169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                                 jbyteArray address) {
71269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
7136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
7146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    const char *response;
7156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
7166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
71769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
71869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
71969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
72069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
72169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
72269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
7236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    response = env->GetStringUTFChars(response_str, NULL);
7246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
72569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->formatted_at_response(response,
72669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                            (bt_bdaddr_t *)addr))!= BT_STATUS_SUCCESS) {
727c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed formatted AT response, status: %d", status);
7286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
72969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
7306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseStringUTFChars(response_str, response);
7316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
7326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
7336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
73469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean atResponseCodeNative(JNIEnv *env, jobject object, jint response_code,
73569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                             jint cmee_code, jbyteArray address) {
73669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
7376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
7386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
7396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
74069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
74169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
74269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
74369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
74469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
74569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
74669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->at_response((bthf_at_response_t) response_code,
74769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava              cmee_code, (bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
748c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed AT response, status: %d", status);
7496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
75069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
7516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
7526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
7536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
7546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean clccResponseNative(JNIEnv *env, jobject object, jint index, jint dir,
7556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                   jint callStatus, jint mode, jboolean mpty, jstring number_str,
75669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                   jint type, jbyteArray address) {
75769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
7586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
759bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan    const char *number = NULL;
7606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
7616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
76269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
76369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
76469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
76569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
76669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
76769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
768bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan    if (number_str)
769bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan        number = env->GetStringUTFChars(number_str, NULL);
7706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
7716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->clcc_response(index, (bthf_call_direction_t) dir,
77269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                (bthf_call_state_t) callStatus,  (bthf_call_mode_t) mode,
77369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                mpty ? BTHF_CALL_MPTY_TYPE_MULTI : BTHF_CALL_MPTY_TYPE_SINGLE,
77469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                number, (bthf_call_addrtype_t) type, (bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
775c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed sending CLCC response, status: %d", status);
7766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
77769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
778bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan    if (number)
779bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan        env->ReleaseStringUTFChars(number_str, number);
7806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
7816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
7826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
7836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean phoneStateChangeNative(JNIEnv *env, jobject object, jint num_active, jint num_held,
7846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                       jint call_state, jstring number_str, jint type) {
7856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
7866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    const char *number;
7876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
7886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
7896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    number = env->GetStringUTFChars(number_str, NULL);
7906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
7916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->phone_state_change(num_active, num_held,
7926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                       (bthf_call_state_t) call_state, number,
7936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                       (bthf_call_addrtype_t) type)) != BT_STATUS_SUCCESS) {
794c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed report phone state change, status: %d", status);
7956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
7966c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseStringUTFChars(number_str, number);
7976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
7986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
7996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
800b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
801b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xiestatic jboolean configureWBSNative(JNIEnv *env, jobject object, jbyteArray address,
802b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie                                   jint codec_config) {
803b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    jbyte *addr;
804b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    bt_status_t status;
805b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
806b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
807b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
808b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    addr = env->GetByteArrayElements(address, NULL);
809b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if (!addr) {
810b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        jniThrowIOException(env, EINVAL);
811b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        return JNI_FALSE;
812b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    }
813b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
814b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if ((status = sBluetoothHfpInterface->configure_wbs((bt_bdaddr_t *)addr,
815b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie                   (bthf_wbs_config_t)codec_config)) != BT_STATUS_SUCCESS){
816b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        ALOGE("Failed HF WBS codec config, status: %d", status);
817b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    }
818b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
819b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
820b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie}
821b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
822b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
8236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic JNINativeMethod sMethods[] = {
8246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"classInitNative", "()V", (void *) classInitNative},
82569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"initializeNative", "(I)V", (void *) initializeNative},
8266654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"cleanupNative", "()V", (void *) cleanupNative},
8276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"connectHfpNative", "([B)Z", (void *) connectHfpNative},
8286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"disconnectHfpNative", "([B)Z", (void *) disconnectHfpNative},
8296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"connectAudioNative", "([B)Z", (void *) connectAudioNative},
8306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"disconnectAudioNative", "([B)Z", (void *) disconnectAudioNative},
83169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"startVoiceRecognitionNative", "([B)Z", (void *) startVoiceRecognitionNative},
83269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"stopVoiceRecognitionNative", "([B)Z", (void *) stopVoiceRecognitionNative},
83369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"setVolumeNative", "(II[B)Z", (void *) setVolumeNative},
8346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"notifyDeviceStatusNative", "(IIII)Z", (void *) notifyDeviceStatusNative},
83569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"copsResponseNative", "(Ljava/lang/String;[B)Z", (void *) copsResponseNative},
83669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"cindResponseNative", "(IIIIIII[B)Z", (void *) cindResponseNative},
83769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"atResponseStringNative", "(Ljava/lang/String;[B)Z", (void *) atResponseStringNative},
83869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"atResponseCodeNative", "(II[B)Z", (void *)atResponseCodeNative},
83969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z", (void *) clccResponseNative},
8406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"phoneStateChangeNative", "(IIILjava/lang/String;I)Z", (void *) phoneStateChangeNative},
841b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    {"configureWBSNative", "([BI)Z", (void *) configureWBSNative},
8426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie};
8436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
8446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieint register_com_android_bluetooth_hfp(JNIEnv* env)
8456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie{
8466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return jniRegisterNativeMethods(env, "com/android/bluetooth/hfp/HeadsetStateMachine",
8476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                    sMethods, NELEM(sMethods));
8486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
8496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
8506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} /* namespace android */
851