Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ae869ab authored by Nitin Srivastava's avatar Nitin Srivastava Committed by Zhihai Xu
Browse files

Multi HF support

1. Added support for Multi HF connections
in Bluetooth application.
2. All connection transition states for
2nd HS onwards is handled in new state-
MultiHFPending.
3. The changes are done to handle proper
state transition for all connected HS.

Change-Id: I033ae57943e50273f9d3cac4c5f8d1624cb9ee09
parent ad304d87
Loading
Loading
Loading
Loading
+301 −72
Original line number Diff line number Diff line
@@ -104,96 +104,250 @@ static void audio_state_callback(bthf_audio_state_t state, bt_bdaddr_t* bd_addr)
    sCallbackEnv->DeleteLocalRef(addr);
}

static void voice_recognition_callback(bthf_vr_state_t state) {
static void voice_recognition_callback(bthf_vr_state_t state, bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint) state);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint) state, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void answer_call_callback() {
static void answer_call_callback(bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void hangup_call_callback() {
static void hangup_call_callback(bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHangupCall);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHangupCall, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void volume_control_callback(bthf_volume_type_t type, int volume) {
static void volume_control_callback(bthf_volume_type_t type, int volume, bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChanged, (jint) type, (jint) volume);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChanged, (jint) type,
                                                  (jint) volume, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void dial_call_callback(char *number) {
static void dial_call_callback(char *number, bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    jstring js_number = sCallbackEnv->NewStringUTF(number);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDialCall,
                                 js_number);
                                 js_number, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(js_number);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void dtmf_cmd_callback(char dtmf) {
static void dtmf_cmd_callback(char dtmf, bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    // TBD dtmf has changed from int to char
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void noice_reduction_callback(bthf_nrec_t nrec) {
static void noice_reduction_callback(bthf_nrec_t nrec, bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }
    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiceReductionEnable,
                                 nrec == BTHF_NREC_START);
                                 nrec == BTHF_NREC_START, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void at_chld_callback(bthf_chld_type_t chld) {
static void at_chld_callback(bthf_chld_type_t chld, bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

static void at_cnum_callback() {
    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void at_cnum_callback(bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void at_cind_callback() {
static void at_cind_callback(bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

static void at_cops_callback() {
    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void at_cops_callback(bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void at_clcc_callback() {
static void at_clcc_callback(bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

static void unknown_at_callback(char *at_string) {
    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void unknown_at_callback(char *at_string, bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    jstring js_at_string = sCallbackEnv->NewStringUTF(at_string);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownAt,
                                 js_at_string);
                                 js_at_string, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(js_at_string);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void key_pressed_callback() {
static void key_pressed_callback(bt_bdaddr_t* bd_addr) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed);
    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for audio state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static bthf_callbacks_t sBluetoothHfpCallbacks = {
@@ -226,20 +380,20 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
    method_onConnectionStateChanged =
        env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
    method_onAudioStateChanged = env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V");
    method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I)V");
    method_onAnswerCall = env->GetMethodID(clazz, "onAnswerCall", "()V");
    method_onHangupCall = env->GetMethodID(clazz, "onHangupCall", "()V");
    method_onVolumeChanged = env->GetMethodID(clazz, "onVolumeChanged", "(II)V");
    method_onDialCall = env->GetMethodID(clazz, "onDialCall", "(Ljava/lang/String;)V");
    method_onSendDtmf = env->GetMethodID(clazz, "onSendDtmf", "(I)V");
    method_onNoiceReductionEnable = env->GetMethodID(clazz, "onNoiceReductionEnable", "(Z)V");
    method_onAtChld = env->GetMethodID(clazz, "onAtChld", "(I)V");
    method_onAtCnum = env->GetMethodID(clazz, "onAtCnum", "()V");
    method_onAtCind = env->GetMethodID(clazz, "onAtCind", "()V");
    method_onAtCops = env->GetMethodID(clazz, "onAtCops", "()V");
    method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "()V");
    method_onUnknownAt = env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;)V");
    method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "()V");
    method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V");
    method_onAnswerCall = env->GetMethodID(clazz, "onAnswerCall", "([B)V");
    method_onHangupCall = env->GetMethodID(clazz, "onHangupCall", "([B)V");
    method_onVolumeChanged = env->GetMethodID(clazz, "onVolumeChanged", "(II[B)V");
    method_onDialCall = env->GetMethodID(clazz, "onDialCall", "(Ljava/lang/String;[B)V");
    method_onSendDtmf = env->GetMethodID(clazz, "onSendDtmf", "(I[B)V");
    method_onNoiceReductionEnable = env->GetMethodID(clazz, "onNoiceReductionEnable", "(Z[B)V");
    method_onAtChld = env->GetMethodID(clazz, "onAtChld", "(I[B)V");
    method_onAtCnum = env->GetMethodID(clazz, "onAtCnum", "([B)V");
    method_onAtCind = env->GetMethodID(clazz, "onAtCind", "([B)V");
    method_onAtCops = env->GetMethodID(clazz, "onAtCops", "([B)V");
    method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "([B)V");
    method_onUnknownAt = env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;[B)V");
    method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "([B)V");

    /*
    if ( (btInf = getBluetoothInterface()) == NULL) {
@@ -265,7 +419,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
    ALOGI("%s: succeeds", __FUNCTION__);
}

static void initializeNative(JNIEnv *env, jobject object) {
static void initializeNative(JNIEnv *env, jobject object, jint max_hf_clients) {
    const bt_interface_t* btInf;
    bt_status_t status;

@@ -292,7 +446,8 @@ static void initializeNative(JNIEnv *env, jobject object) {
        return;
    }

    if ( (status = sBluetoothHfpInterface->init(&sBluetoothHfpCallbacks)) != BT_STATUS_SUCCESS) {
    if ( (status = sBluetoothHfpInterface->init(&sBluetoothHfpCallbacks,
          max_hf_clients)) != BT_STATUS_SUCCESS) {
        ALOGE("Failed to initialize Bluetooth HFP, status: %d", status);
        sBluetoothHfpInterface = NULL;
        return;
@@ -402,34 +557,61 @@ static jboolean disconnectAudioNative(JNIEnv *env, jobject object, jbyteArray ad
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean startVoiceRecognitionNative(JNIEnv *env, jobject object) {
static jboolean startVoiceRecognitionNative(JNIEnv *env, jobject object, jbyteArray address) {
    jbyte *addr;
    bt_status_t status;
    if (!sBluetoothHfpInterface) return JNI_FALSE;

    if ( (status = sBluetoothHfpInterface->start_voice_recognition()) != BT_STATUS_SUCCESS) {
    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        jniThrowIOException(env, EINVAL);
        return JNI_FALSE;
    }

    if ( (status = sBluetoothHfpInterface->start_voice_recognition((bt_bdaddr_t *) addr))
                                          != BT_STATUS_SUCCESS) {
        ALOGE("Failed to start voice recognition, status: %d", status);
    }
    env->ReleaseByteArrayElements(address, addr, 0);
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean stopVoiceRecognitionNative(JNIEnv *env, jobject object) {
static jboolean stopVoiceRecognitionNative(JNIEnv *env, jobject object, jbyteArray address) {
    jbyte *addr;
    bt_status_t status;
    if (!sBluetoothHfpInterface) return JNI_FALSE;

    if ( (status = sBluetoothHfpInterface->stop_voice_recognition()) != BT_STATUS_SUCCESS) {
    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        jniThrowIOException(env, EINVAL);
        return JNI_FALSE;
    }

    if ( (status = sBluetoothHfpInterface->stop_voice_recognition((bt_bdaddr_t *) addr))
                                     != BT_STATUS_SUCCESS) {
        ALOGE("Failed to stop voice recognition, status: %d", status);
    }
    env->ReleaseByteArrayElements(address, addr, 0);
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean setVolumeNative(JNIEnv *env, jobject object, jint volume_type, jint volume) {
static jboolean setVolumeNative(JNIEnv *env, jobject object, jint volume_type,
                                     jint volume, jbyteArray address) {
    jbyte *addr;
    bt_status_t status;
    if (!sBluetoothHfpInterface) return JNI_FALSE;

    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        jniThrowIOException(env, EINVAL);
        return JNI_FALSE;
    }

    if ( (status = sBluetoothHfpInterface->volume_control((bthf_volume_type_t) volume_type,
                                                          volume)) != BT_STATUS_SUCCESS) {
                                volume, (bt_bdaddr_t *) addr)) != BT_STATUS_SUCCESS) {
        ALOGE("FAILED to control volume, status: %d", status);
    }
    env->ReleaseByteArrayElements(address, addr, 0);
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

@@ -447,76 +629,123 @@ static jboolean notifyDeviceStatusNative(JNIEnv *env, jobject object,
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean copsResponseNative(JNIEnv *env, jobject object, jstring operator_str) {
static jboolean copsResponseNative(JNIEnv *env, jobject object, jstring operator_str,
                                              jbyteArray address) {
    jbyte *addr;
    bt_status_t status;
    const char *operator_name;
    if (!sBluetoothHfpInterface) return JNI_FALSE;

    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        jniThrowIOException(env, EINVAL);
        return JNI_FALSE;
    }

    operator_name = env->GetStringUTFChars(operator_str, NULL);

    if ( (status = sBluetoothHfpInterface->cops_response(operator_name)) != BT_STATUS_SUCCESS) {
    if ( (status = sBluetoothHfpInterface->cops_response(operator_name,(bt_bdaddr_t *) addr))
                                                  != BT_STATUS_SUCCESS) {
        ALOGE("Failed sending cops response, status: %d", status);
    }
    env->ReleaseByteArrayElements(address, addr, 0);
    env->ReleaseStringUTFChars(operator_str, operator_name);
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean cindResponseNative(JNIEnv *env, jobject object,
                                   jint service, jint num_active, jint num_held, jint call_state,
                                   jint signal, jint roam, jint battery_charge) {
                                   jint signal, jint roam, jint battery_charge, jbyteArray address) {
    jbyte *addr;
    bt_status_t status;

    ALOGI("%s: sBluetoothHfpInterface: %p", __FUNCTION__, sBluetoothHfpInterface);
    if (!sBluetoothHfpInterface) return JNI_FALSE;

    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        jniThrowIOException(env, EINVAL);
        return JNI_FALSE;
    }

    if ( (status = sBluetoothHfpInterface->cind_response(service, num_active, num_held,
                       (bthf_call_state_t) call_state,
                       signal, roam, battery_charge)) != BT_STATUS_SUCCESS) {
                       signal, roam, battery_charge, (bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
        ALOGE("Failed cind_response, status: %d", status);
    }
    env->ReleaseByteArrayElements(address, addr, 0);
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}


static jboolean atResponseStringNative(JNIEnv *env, jobject object, jstring response_str) {
static jboolean atResponseStringNative(JNIEnv *env, jobject object, jstring response_str,
                                                 jbyteArray address) {
    jbyte *addr;
    bt_status_t status;
    const char *response;
    if (!sBluetoothHfpInterface) return JNI_FALSE;

    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        jniThrowIOException(env, EINVAL);
        return JNI_FALSE;
    }

    response = env->GetStringUTFChars(response_str, NULL);

    if ( (status = sBluetoothHfpInterface->formatted_at_response(response)) != BT_STATUS_SUCCESS) {
    if ( (status = sBluetoothHfpInterface->formatted_at_response(response,
                            (bt_bdaddr_t *)addr))!= BT_STATUS_SUCCESS) {
        ALOGE("Failed formatted AT response, status: %d", status);
    }
    env->ReleaseByteArrayElements(address, addr, 0);
    env->ReleaseStringUTFChars(response_str, response);
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean atResponseCodeNative(JNIEnv *env, jobject object, jint response_code, jint cmee_code) {
static jboolean atResponseCodeNative(JNIEnv *env, jobject object, jint response_code,
                                             jint cmee_code, jbyteArray address) {
    jbyte *addr;
    bt_status_t status;
    if (!sBluetoothHfpInterface) return JNI_FALSE;

    if ( (status = sBluetoothHfpInterface->at_response((bthf_at_response_t) response_code, cmee_code)) !=
         BT_STATUS_SUCCESS) {
    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        jniThrowIOException(env, EINVAL);
        return JNI_FALSE;
    }

    if ( (status = sBluetoothHfpInterface->at_response((bthf_at_response_t) response_code,
              cmee_code, (bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
        ALOGE("Failed AT response, status: %d", status);
    }
    env->ReleaseByteArrayElements(address, addr, 0);
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean clccResponseNative(JNIEnv *env, jobject object, jint index, jint dir,
                                   jint callStatus, jint mode, jboolean mpty, jstring number_str,
                                   jint type) {
                                   jint type, jbyteArray address) {
    jbyte *addr;
    bt_status_t status;
    const char *number = NULL;
    if (!sBluetoothHfpInterface) return JNI_FALSE;

    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        jniThrowIOException(env, EINVAL);
        return JNI_FALSE;
    }

    if (number_str)
        number = env->GetStringUTFChars(number_str, NULL);

    if ( (status = sBluetoothHfpInterface->clcc_response(index, (bthf_call_direction_t) dir,
                (bthf_call_state_t) callStatus,  (bthf_call_mode_t) mode,
                mpty ? BTHF_CALL_MPTY_TYPE_MULTI : BTHF_CALL_MPTY_TYPE_SINGLE,
                     number, (bthf_call_addrtype_t) type)) != BT_STATUS_SUCCESS) {
                number, (bthf_call_addrtype_t) type, (bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
        ALOGE("Failed sending CLCC response, status: %d", status);
    }
    env->ReleaseByteArrayElements(address, addr, 0);
    if (number)
        env->ReleaseStringUTFChars(number_str, number);
    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
@@ -541,21 +770,21 @@ static jboolean phoneStateChangeNative(JNIEnv *env, jobject object, jint num_act

static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void *) classInitNative},
    {"initializeNative", "()V", (void *) initializeNative},
    {"initializeNative", "(I)V", (void *) initializeNative},
    {"cleanupNative", "()V", (void *) cleanupNative},
    {"connectHfpNative", "([B)Z", (void *) connectHfpNative},
    {"disconnectHfpNative", "([B)Z", (void *) disconnectHfpNative},
    {"connectAudioNative", "([B)Z", (void *) connectAudioNative},
    {"disconnectAudioNative", "([B)Z", (void *) disconnectAudioNative},
    {"startVoiceRecognitionNative", "()Z", (void *) startVoiceRecognitionNative},
    {"stopVoiceRecognitionNative", "()Z", (void *) stopVoiceRecognitionNative},
    {"setVolumeNative", "(II)Z", (void *) setVolumeNative},
    {"startVoiceRecognitionNative", "([B)Z", (void *) startVoiceRecognitionNative},
    {"stopVoiceRecognitionNative", "([B)Z", (void *) stopVoiceRecognitionNative},
    {"setVolumeNative", "(II[B)Z", (void *) setVolumeNative},
    {"notifyDeviceStatusNative", "(IIII)Z", (void *) notifyDeviceStatusNative},
    {"copsResponseNative", "(Ljava/lang/String;)Z", (void *) copsResponseNative},
    {"cindResponseNative", "(IIIIIII)Z", (void *) cindResponseNative},
    {"atResponseStringNative", "(Ljava/lang/String;)Z", (void *) atResponseStringNative},
    {"atResponseCodeNative", "(II)Z", (void *)atResponseCodeNative},
    {"clccResponseNative", "(IIIIZLjava/lang/String;I)Z", (void *) clccResponseNative},
    {"copsResponseNative", "(Ljava/lang/String;[B)Z", (void *) copsResponseNative},
    {"cindResponseNative", "(IIIIIII[B)Z", (void *) cindResponseNative},
    {"atResponseStringNative", "(Ljava/lang/String;[B)Z", (void *) atResponseStringNative},
    {"atResponseCodeNative", "(II[B)Z", (void *)atResponseCodeNative},
    {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z", (void *) clccResponseNative},
    {"phoneStateChangeNative", "(IIILjava/lang/String;I)Z", (void *) phoneStateChangeNative},
};

+4 −3

File changed.

Preview size limit exceeded, changes collapsed.

+35 −18

File changed.

Preview size limit exceeded, changes collapsed.

+5 −1
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.bluetooth.BluetoothDevice;


// Note:
// All methods in this class are not thread safe, donot call them from
@@ -327,10 +329,12 @@ class HeadsetClccResponse {
}

class HeadsetVendorSpecificResultCode {
    BluetoothDevice mDevice;
    String mCommand;
    String mArg;

    public HeadsetVendorSpecificResultCode(String command, String arg) {
    public HeadsetVendorSpecificResultCode(BluetoothDevice device, String command, String arg) {
        mDevice = device;
        mCommand = command;
        mArg = arg;
    }
+3 −1

File changed.

Preview size limit exceeded, changes collapsed.

Loading