Loading android/app/jni/com_android_bluetooth_hfp.cpp +131 −78 Original line number Original line Diff line number Diff line Loading @@ -406,19 +406,21 @@ static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients, std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex); std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex); const bt_interface_t* btInf = getBluetoothInterface(); const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { if (!btInf) { ALOGE("Bluetooth module is not loaded"); ALOGE("%s: Bluetooth module is not loaded", __func__); jniThrowIOException(env, EINVAL); return; return; } } if (sBluetoothHfpInterface != nullptr) { if (sBluetoothHfpInterface) { ALOGW("Cleaning up Bluetooth Handsfree Interface before initializing..."); ALOGI("%s: Cleaning up Bluetooth Handsfree Interface before initializing", __func__); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface = nullptr; sBluetoothHfpInterface = nullptr; } } if (mCallbacksObj != nullptr) { if (mCallbacksObj) { ALOGW("Cleaning up Bluetooth Handsfree callback object"); ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__); env->DeleteGlobalRef(mCallbacksObj); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; mCallbacksObj = nullptr; } } Loading @@ -426,16 +428,16 @@ static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients, sBluetoothHfpInterface = sBluetoothHfpInterface = (bluetooth::headset::Interface*)btInf->get_profile_interface( (bluetooth::headset::Interface*)btInf->get_profile_interface( BT_PROFILE_HANDSFREE_ID); BT_PROFILE_HANDSFREE_ID); if (sBluetoothHfpInterface == nullptr) { if (!sBluetoothHfpInterface) { ALOGE("Failed to get Bluetooth Handsfree Interface"); ALOGW("%s: Failed to get Bluetooth Handsfree Interface", __func__); return; jniThrowIOException(env, EINVAL); } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->Init(JniHeadsetCallbacks::GetInstance(), sBluetoothHfpInterface->Init(JniHeadsetCallbacks::GetInstance(), max_hf_clients, inband_ringing_enabled); max_hf_clients, inband_ringing_enabled); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed to initialize Bluetooth HFP, status: %d", status); ALOGE("%s: Failed to initialize Bluetooth Handsfree Interface, status: %d", __func__, status); sBluetoothHfpInterface = nullptr; sBluetoothHfpInterface = nullptr; return; return; } } Loading @@ -449,18 +451,18 @@ static void cleanupNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); const bt_interface_t* btInf = getBluetoothInterface(); if (!btInf) { if (!btInf) { ALOGE("Bluetooth module is not loaded"); ALOGW("%s: Bluetooth module is not loaded", __func__); return; return; } } if (sBluetoothHfpInterface) { if (sBluetoothHfpInterface) { ALOGW("Cleaning up Bluetooth Handsfree Interface..."); ALOGI("%s: Cleaning up Bluetooth Handsfree Interface", __func__); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface = nullptr; sBluetoothHfpInterface = nullptr; } } if (mCallbacksObj) { if (mCallbacksObj) { ALOGW("Cleaning up Bluetooth Handsfree callback object"); ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__); env->DeleteGlobalRef(mCallbacksObj); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; mCallbacksObj = nullptr; } } Loading @@ -468,16 +470,18 @@ static void cleanupNative(JNIEnv* env, jobject object) { static jboolean connectHfpNative(JNIEnv* env, jobject object, static jboolean connectHfpNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { ALOGI("%s: sBluetoothHfpInterface: %p", __func__, sBluetoothHfpInterface); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); bt_status_t status = sBluetoothHfpInterface->Connect((RawAddress*)addr); bt_status_t status = sBluetoothHfpInterface->Connect((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed HF connection, status: %d", status); ALOGE("Failed HF connection, status: %d", status); Loading @@ -489,14 +493,17 @@ static jboolean connectHfpNative(JNIEnv* env, jobject object, static jboolean disconnectHfpNative(JNIEnv* env, jobject object, static jboolean disconnectHfpNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); bt_status_t status = sBluetoothHfpInterface->Disconnect((RawAddress*)addr); bt_status_t status = sBluetoothHfpInterface->Disconnect((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed HF disconnection, status: %d", status); ALOGE("Failed HF disconnection, status: %d", status); Loading @@ -508,14 +515,17 @@ static jboolean disconnectHfpNative(JNIEnv* env, jobject object, static jboolean connectAudioNative(JNIEnv* env, jobject object, static jboolean connectAudioNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); bt_status_t status = sBluetoothHfpInterface->ConnectAudio((RawAddress*)addr); bt_status_t status = sBluetoothHfpInterface->ConnectAudio((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed HF audio connection, status: %d", status); ALOGE("Failed HF audio connection, status: %d", status); Loading @@ -527,14 +537,17 @@ static jboolean connectAudioNative(JNIEnv* env, jobject object, static jboolean disconnectAudioNative(JNIEnv* env, jobject object, static jboolean disconnectAudioNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); bt_status_t status = bt_status_t status = sBluetoothHfpInterface->DisconnectAudio((RawAddress*)addr); sBluetoothHfpInterface->DisconnectAudio((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -547,14 +560,16 @@ static jboolean disconnectAudioNative(JNIEnv* env, jobject object, static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object, static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr); sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -567,14 +582,16 @@ static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object, static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object, static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->StopVoiceRecognition((RawAddress*)addr); sBluetoothHfpInterface->StopVoiceRecognition((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -587,14 +604,16 @@ static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object, static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type, static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type, jint volume, jbyteArray address) { jint volume, jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = sBluetoothHfpInterface->VolumeControl( bt_status_t status = sBluetoothHfpInterface->VolumeControl( (bluetooth::headset::bthf_volume_type_t)volume_type, volume, (bluetooth::headset::bthf_volume_type_t)volume_type, volume, (RawAddress*)addr); (RawAddress*)addr); Loading @@ -607,14 +626,24 @@ static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type, static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object, static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object, jint network_state, jint service_type, jint network_state, jint service_type, jint signal, jint battery_charge) { jint signal, jint battery_charge, jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); return JNI_FALSE; } bt_status_t status = sBluetoothHfpInterface->DeviceStatusNotification( bt_status_t status = sBluetoothHfpInterface->DeviceStatusNotification( (bluetooth::headset::bthf_network_state_t)network_state, (bluetooth::headset::bthf_network_state_t)network_state, (bluetooth::headset::bthf_service_type_t)service_type, signal, (bluetooth::headset::bthf_service_type_t)service_type, signal, battery_charge); battery_charge, (RawAddress*)addr); env->ReleaseByteArrayElements(address, addr, 0); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("FAILED to notify device status, status: %d", status); ALOGE("FAILED to notify device status, status: %d", status); } } Loading @@ -624,16 +653,17 @@ static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object, static jboolean copsResponseNative(JNIEnv* env, jobject object, static jboolean copsResponseNative(JNIEnv* env, jobject object, jstring operator_str, jbyteArray address) { jstring operator_str, jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } const char* operator_name = env->GetStringUTFChars(operator_str, nullptr); const char* operator_name = env->GetStringUTFChars(operator_str, nullptr); bt_status_t status = bt_status_t status = sBluetoothHfpInterface->CopsResponse(operator_name, (RawAddress*)addr); sBluetoothHfpInterface->CopsResponse(operator_name, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -648,23 +678,23 @@ static jboolean cindResponseNative(JNIEnv* env, jobject object, jint service, jint num_active, jint num_held, jint num_active, jint num_held, jint call_state, jint signal, jint roam, jint call_state, jint signal, jint roam, jint battery_charge, jbyteArray address) { jint battery_charge, jbyteArray address) { ALOGI("%s: sBluetoothHfpInterface: %p", __func__, sBluetoothHfpInterface); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = sBluetoothHfpInterface->CindResponse( bt_status_t status = sBluetoothHfpInterface->CindResponse( service, num_active, num_held, service, num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state, signal, roam, (bluetooth::headset::bthf_call_state_t)call_state, signal, roam, battery_charge, (RawAddress*)addr); battery_charge, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed cind_response, status: %d", status); ALOGE("%s: failed, status: %d", __func__, status); } } env->ReleaseByteArrayElements(address, addr, 0); env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; Loading @@ -674,16 +704,17 @@ static jboolean atResponseStringNative(JNIEnv* env, jobject object, jstring response_str, jstring response_str, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } const char* response = env->GetStringUTFChars(response_str, nullptr); const char* response = env->GetStringUTFChars(response_str, nullptr); bt_status_t status = bt_status_t status = sBluetoothHfpInterface->FormattedAtResponse(response, (RawAddress*)addr); sBluetoothHfpInterface->FormattedAtResponse(response, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -698,14 +729,16 @@ static jboolean atResponseCodeNative(JNIEnv* env, jobject object, jint response_code, jint cmee_code, jint response_code, jint cmee_code, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = sBluetoothHfpInterface->AtResponse( bt_status_t status = sBluetoothHfpInterface->AtResponse( (bluetooth::headset::bthf_at_response_t)response_code, cmee_code, (bluetooth::headset::bthf_at_response_t)response_code, cmee_code, (RawAddress*)addr); (RawAddress*)addr); Loading @@ -721,17 +754,20 @@ static jboolean clccResponseNative(JNIEnv* env, jobject object, jint index, jboolean mpty, jstring number_str, jint type, jboolean mpty, jstring number_str, jint type, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } const char* number = nullptr; const char* number = nullptr; if (number_str) number = env->GetStringUTFChars(number_str, nullptr); if (number_str) { number = env->GetStringUTFChars(number_str, nullptr); } bt_status_t status = sBluetoothHfpInterface->ClccResponse( bt_status_t status = sBluetoothHfpInterface->ClccResponse( index, (bluetooth::headset::bthf_call_direction_t)dir, index, (bluetooth::headset::bthf_call_direction_t)dir, (bluetooth::headset::bthf_call_state_t)callStatus, (bluetooth::headset::bthf_call_state_t)callStatus, Loading @@ -744,34 +780,47 @@ static jboolean clccResponseNative(JNIEnv* env, jobject object, jint index, ALOGE("Failed sending CLCC response, status: %d", status); ALOGE("Failed sending CLCC response, status: %d", status); } } env->ReleaseByteArrayElements(address, addr, 0); env->ReleaseByteArrayElements(address, addr, 0); if (number) env->ReleaseStringUTFChars(number_str, number); if (number) { env->ReleaseStringUTFChars(number_str, number); } return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } } static jboolean phoneStateChangeNative(JNIEnv* env, jobject object, static jboolean phoneStateChangeNative(JNIEnv* env, jobject object, jint num_active, jint num_held, jint num_active, jint num_held, jint call_state, jstring number_str, jint call_state, jstring number_str, jint type) { jint type, jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); return JNI_FALSE; } const char* number = env->GetStringUTFChars(number_str, nullptr); const char* number = env->GetStringUTFChars(number_str, nullptr); bt_status_t status = sBluetoothHfpInterface->PhoneStateChange( bt_status_t status = sBluetoothHfpInterface->PhoneStateChange( num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state, num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state, number, (bluetooth::headset::bthf_call_addrtype_t)type); number, (bluetooth::headset::bthf_call_addrtype_t)type, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed report phone state change, status: %d", status); ALOGE("Failed report phone state change, status: %d", status); } } env->ReleaseStringUTFChars(number_str, number); env->ReleaseStringUTFChars(number_str, number); env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } } static jboolean setScoAllowedNative(JNIEnv* env, jobject object, static jboolean setScoAllowedNative(JNIEnv* env, jobject object, jboolean value) { jboolean value) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } bt_status_t status = sBluetoothHfpInterface->SetScoAllowed(value == JNI_TRUE); bt_status_t status = sBluetoothHfpInterface->SetScoAllowed(value == JNI_TRUE); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed HF set sco allowed, status: %d", status); ALOGE("Failed HF set sco allowed, status: %d", status); Loading @@ -782,14 +831,16 @@ static jboolean setScoAllowedNative(JNIEnv* env, jobject object, static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value, static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, NULL); jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->SendBsir(value == JNI_TRUE, (RawAddress*)addr); sBluetoothHfpInterface->SendBsir(value == JNI_TRUE, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -802,14 +853,16 @@ static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value, static jboolean setActiveDeviceNative(JNIEnv* env, jobject object, static jboolean setActiveDeviceNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, NULL); jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->SetActiveDevice((RawAddress*)addr); sBluetoothHfpInterface->SetActiveDevice((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -831,7 +884,7 @@ static JNINativeMethod sMethods[] = { (void*)startVoiceRecognitionNative}, (void*)startVoiceRecognitionNative}, {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative}, {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative}, {"setVolumeNative", "(II[B)Z", (void*)setVolumeNative}, {"setVolumeNative", "(II[B)Z", (void*)setVolumeNative}, {"notifyDeviceStatusNative", "(IIII)Z", (void*)notifyDeviceStatusNative}, {"notifyDeviceStatusNative", "(IIII[B)Z", (void*)notifyDeviceStatusNative}, {"copsResponseNative", "(Ljava/lang/String;[B)Z", {"copsResponseNative", "(Ljava/lang/String;[B)Z", (void*)copsResponseNative}, (void*)copsResponseNative}, {"cindResponseNative", "(IIIIIII[B)Z", (void*)cindResponseNative}, {"cindResponseNative", "(IIIIIII[B)Z", (void*)cindResponseNative}, Loading @@ -840,7 +893,7 @@ static JNINativeMethod sMethods[] = { {"atResponseCodeNative", "(II[B)Z", (void*)atResponseCodeNative}, {"atResponseCodeNative", "(II[B)Z", (void*)atResponseCodeNative}, {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z", {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z", (void*)clccResponseNative}, (void*)clccResponseNative}, {"phoneStateChangeNative", "(IIILjava/lang/String;I)Z", {"phoneStateChangeNative", "(IIILjava/lang/String;I[B)Z", (void*)phoneStateChangeNative}, (void*)phoneStateChangeNative}, {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative}, {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative}, {"sendBsirNative", "(Z[B)Z", (void*)sendBsirNative}, {"sendBsirNative", "(Z[B)Z", (void*)sendBsirNative}, Loading android/app/src/com/android/bluetooth/Utils.java +27 −0 Original line number Original line Diff line number Diff line Loading @@ -355,4 +355,31 @@ public final class Utils { public static int millsToUnit(int milliseconds) { public static int millsToUnit(int milliseconds) { return (int) (TimeUnit.MILLISECONDS.toMicros(milliseconds) / MICROS_PER_UNIT); return (int) (TimeUnit.MILLISECONDS.toMicros(milliseconds) / MICROS_PER_UNIT); } } /** * Check if we are running in BluetoothInstrumentationTest context by trying to load * com.android.bluetooth.FileSystemWriteTest. If we are not in Instrumentation test mode, this * class should not be found. Thus, the assumption is that FileSystemWriteTest must exist. * If FileSystemWriteTest is removed in the future, another test class in * BluetoothInstrumentationTest should be used instead * * @return true if in BluetoothInstrumentationTest, false otherwise */ public static boolean isInstrumentationTestMode() { try { return Class.forName("com.android.bluetooth.FileSystemWriteTest") != null; } catch (ClassNotFoundException exception) { return false; } } /** * Throws {@link IllegalStateException} if we are not in BluetoothInstrumentationTest. Useful * for ensuring certain methods only get called in BluetoothInstrumentationTest */ public static void enforceInstrumentationTestMode() { if (!isInstrumentationTestMode()) { throw new IllegalStateException("Not in BluetoothInstrumentationTest"); } } } } android/app/src/com/android/bluetooth/btservice/AdapterService.java +9 −1 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,7 @@ import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; import com.android.bluetooth.gatt.GattService; import com.android.bluetooth.gatt.GattService; import com.android.bluetooth.sdp.SdpManager; import com.android.bluetooth.sdp.SdpManager; import com.android.internal.R; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; import com.android.internal.app.IBatteryStats; import java.io.FileDescriptor; import java.io.FileDescriptor; Loading Loading @@ -1979,7 +1980,14 @@ public class AdapterService extends Service { return deviceProp.getBluetoothClass(); return deviceProp.getBluetoothClass(); } } ParcelUuid[] getRemoteUuids(BluetoothDevice device) { /** * Get UUIDs for service supported by a remote device * * @param device the remote device that we want to get UUIDs from * @return */ @VisibleForTesting public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); if (deviceProp == null) { if (deviceProp == null) { Loading android/app/src/com/android/bluetooth/btservice/ProfileService.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,7 @@ public abstract class ProfileService extends Service { private static final String TAG = "BluetoothProfileService"; private static final String TAG = "BluetoothProfileService"; //For Debugging only //For Debugging only private static HashMap<String, Integer> sReferenceCount = new HashMap<String, Integer>(); private static final HashMap<String, Integer> sReferenceCount = new HashMap<String, Integer>(); public static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; public static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; public static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; public static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; Loading android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java +10 −7 Original line number Original line Diff line number Diff line Loading @@ -346,13 +346,14 @@ public class HeadsetNativeInterface { /** /** * Combined device status change notification * Combined device status change notification * * * @param device target device * @param deviceState device status object * @param deviceState device status object * @return True on success, False on failure * @return True on success, False on failure */ */ @VisibleForTesting @VisibleForTesting public boolean notifyDeviceStatus(HeadsetDeviceState deviceState) { public boolean notifyDeviceStatus(BluetoothDevice device, HeadsetDeviceState deviceState) { return notifyDeviceStatusNative(deviceState.mService, deviceState.mRoam, return notifyDeviceStatusNative(deviceState.mService, deviceState.mRoam, deviceState.mSignal, deviceState.mBatteryCharge); deviceState.mSignal, deviceState.mBatteryCharge, Utils.getByteAddress(device)); } } /** /** Loading Loading @@ -401,13 +402,15 @@ public class HeadsetNativeInterface { * This will take one of the values from BtHfCallState * This will take one of the values from BtHfCallState * 3. number & type: valid only for incoming & waiting call * 3. number & type: valid only for incoming & waiting call * * * @param device target device for this update * @param callState callstate structure * @param callState callstate structure * @return True on success, False on failure * @return True on success, False on failure */ */ @VisibleForTesting @VisibleForTesting public boolean phoneStateChange(HeadsetCallState callState) { public boolean phoneStateChange(BluetoothDevice device, HeadsetCallState callState) { return phoneStateChangeNative(callState.mNumActive, callState.mNumHeld, return phoneStateChangeNative(callState.mNumActive, callState.mNumHeld, callState.mCallState, callState.mNumber, callState.mType); callState.mCallState, callState.mNumber, callState.mType, Utils.getByteAddress(device)); } } /** /** Loading Loading @@ -472,7 +475,7 @@ public class HeadsetNativeInterface { int callState, int signal, int roam, int batteryCharge, byte[] address); int callState, int signal, int roam, int batteryCharge, byte[] address); private native boolean notifyDeviceStatusNative(int networkState, int serviceType, int signal, private native boolean notifyDeviceStatusNative(int networkState, int serviceType, int signal, int batteryCharge); int batteryCharge, byte[] address); private native boolean clccResponseNative(int index, int dir, int status, int mode, private native boolean clccResponseNative(int index, int dir, int status, int mode, boolean mpty, String number, int type, byte[] address); boolean mpty, String number, int type, byte[] address); Loading @@ -480,7 +483,7 @@ public class HeadsetNativeInterface { private native boolean copsResponseNative(String operatorName, byte[] address); private native boolean copsResponseNative(String operatorName, byte[] address); private native boolean phoneStateChangeNative(int numActive, int numHeld, int callState, private native boolean phoneStateChangeNative(int numActive, int numHeld, int callState, String number, int type); String number, int type, byte[] address); private native boolean setScoAllowedNative(boolean value); private native boolean setScoAllowedNative(boolean value); Loading Loading
android/app/jni/com_android_bluetooth_hfp.cpp +131 −78 Original line number Original line Diff line number Diff line Loading @@ -406,19 +406,21 @@ static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients, std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex); std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex); const bt_interface_t* btInf = getBluetoothInterface(); const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { if (!btInf) { ALOGE("Bluetooth module is not loaded"); ALOGE("%s: Bluetooth module is not loaded", __func__); jniThrowIOException(env, EINVAL); return; return; } } if (sBluetoothHfpInterface != nullptr) { if (sBluetoothHfpInterface) { ALOGW("Cleaning up Bluetooth Handsfree Interface before initializing..."); ALOGI("%s: Cleaning up Bluetooth Handsfree Interface before initializing", __func__); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface = nullptr; sBluetoothHfpInterface = nullptr; } } if (mCallbacksObj != nullptr) { if (mCallbacksObj) { ALOGW("Cleaning up Bluetooth Handsfree callback object"); ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__); env->DeleteGlobalRef(mCallbacksObj); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; mCallbacksObj = nullptr; } } Loading @@ -426,16 +428,16 @@ static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients, sBluetoothHfpInterface = sBluetoothHfpInterface = (bluetooth::headset::Interface*)btInf->get_profile_interface( (bluetooth::headset::Interface*)btInf->get_profile_interface( BT_PROFILE_HANDSFREE_ID); BT_PROFILE_HANDSFREE_ID); if (sBluetoothHfpInterface == nullptr) { if (!sBluetoothHfpInterface) { ALOGE("Failed to get Bluetooth Handsfree Interface"); ALOGW("%s: Failed to get Bluetooth Handsfree Interface", __func__); return; jniThrowIOException(env, EINVAL); } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->Init(JniHeadsetCallbacks::GetInstance(), sBluetoothHfpInterface->Init(JniHeadsetCallbacks::GetInstance(), max_hf_clients, inband_ringing_enabled); max_hf_clients, inband_ringing_enabled); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed to initialize Bluetooth HFP, status: %d", status); ALOGE("%s: Failed to initialize Bluetooth Handsfree Interface, status: %d", __func__, status); sBluetoothHfpInterface = nullptr; sBluetoothHfpInterface = nullptr; return; return; } } Loading @@ -449,18 +451,18 @@ static void cleanupNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); const bt_interface_t* btInf = getBluetoothInterface(); if (!btInf) { if (!btInf) { ALOGE("Bluetooth module is not loaded"); ALOGW("%s: Bluetooth module is not loaded", __func__); return; return; } } if (sBluetoothHfpInterface) { if (sBluetoothHfpInterface) { ALOGW("Cleaning up Bluetooth Handsfree Interface..."); ALOGI("%s: Cleaning up Bluetooth Handsfree Interface", __func__); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface = nullptr; sBluetoothHfpInterface = nullptr; } } if (mCallbacksObj) { if (mCallbacksObj) { ALOGW("Cleaning up Bluetooth Handsfree callback object"); ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__); env->DeleteGlobalRef(mCallbacksObj); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; mCallbacksObj = nullptr; } } Loading @@ -468,16 +470,18 @@ static void cleanupNative(JNIEnv* env, jobject object) { static jboolean connectHfpNative(JNIEnv* env, jobject object, static jboolean connectHfpNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { ALOGI("%s: sBluetoothHfpInterface: %p", __func__, sBluetoothHfpInterface); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); bt_status_t status = sBluetoothHfpInterface->Connect((RawAddress*)addr); bt_status_t status = sBluetoothHfpInterface->Connect((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed HF connection, status: %d", status); ALOGE("Failed HF connection, status: %d", status); Loading @@ -489,14 +493,17 @@ static jboolean connectHfpNative(JNIEnv* env, jobject object, static jboolean disconnectHfpNative(JNIEnv* env, jobject object, static jboolean disconnectHfpNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); bt_status_t status = sBluetoothHfpInterface->Disconnect((RawAddress*)addr); bt_status_t status = sBluetoothHfpInterface->Disconnect((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed HF disconnection, status: %d", status); ALOGE("Failed HF disconnection, status: %d", status); Loading @@ -508,14 +515,17 @@ static jboolean disconnectHfpNative(JNIEnv* env, jobject object, static jboolean connectAudioNative(JNIEnv* env, jobject object, static jboolean connectAudioNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); bt_status_t status = sBluetoothHfpInterface->ConnectAudio((RawAddress*)addr); bt_status_t status = sBluetoothHfpInterface->ConnectAudio((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed HF audio connection, status: %d", status); ALOGE("Failed HF audio connection, status: %d", status); Loading @@ -527,14 +537,17 @@ static jboolean connectAudioNative(JNIEnv* env, jobject object, static jboolean disconnectAudioNative(JNIEnv* env, jobject object, static jboolean disconnectAudioNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str()); bt_status_t status = bt_status_t status = sBluetoothHfpInterface->DisconnectAudio((RawAddress*)addr); sBluetoothHfpInterface->DisconnectAudio((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -547,14 +560,16 @@ static jboolean disconnectAudioNative(JNIEnv* env, jobject object, static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object, static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr); sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -567,14 +582,16 @@ static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object, static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object, static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->StopVoiceRecognition((RawAddress*)addr); sBluetoothHfpInterface->StopVoiceRecognition((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -587,14 +604,16 @@ static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object, static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type, static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type, jint volume, jbyteArray address) { jint volume, jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = sBluetoothHfpInterface->VolumeControl( bt_status_t status = sBluetoothHfpInterface->VolumeControl( (bluetooth::headset::bthf_volume_type_t)volume_type, volume, (bluetooth::headset::bthf_volume_type_t)volume_type, volume, (RawAddress*)addr); (RawAddress*)addr); Loading @@ -607,14 +626,24 @@ static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type, static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object, static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object, jint network_state, jint service_type, jint network_state, jint service_type, jint signal, jint battery_charge) { jint signal, jint battery_charge, jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); return JNI_FALSE; } bt_status_t status = sBluetoothHfpInterface->DeviceStatusNotification( bt_status_t status = sBluetoothHfpInterface->DeviceStatusNotification( (bluetooth::headset::bthf_network_state_t)network_state, (bluetooth::headset::bthf_network_state_t)network_state, (bluetooth::headset::bthf_service_type_t)service_type, signal, (bluetooth::headset::bthf_service_type_t)service_type, signal, battery_charge); battery_charge, (RawAddress*)addr); env->ReleaseByteArrayElements(address, addr, 0); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("FAILED to notify device status, status: %d", status); ALOGE("FAILED to notify device status, status: %d", status); } } Loading @@ -624,16 +653,17 @@ static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object, static jboolean copsResponseNative(JNIEnv* env, jobject object, static jboolean copsResponseNative(JNIEnv* env, jobject object, jstring operator_str, jbyteArray address) { jstring operator_str, jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } const char* operator_name = env->GetStringUTFChars(operator_str, nullptr); const char* operator_name = env->GetStringUTFChars(operator_str, nullptr); bt_status_t status = bt_status_t status = sBluetoothHfpInterface->CopsResponse(operator_name, (RawAddress*)addr); sBluetoothHfpInterface->CopsResponse(operator_name, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -648,23 +678,23 @@ static jboolean cindResponseNative(JNIEnv* env, jobject object, jint service, jint num_active, jint num_held, jint num_active, jint num_held, jint call_state, jint signal, jint roam, jint call_state, jint signal, jint roam, jint battery_charge, jbyteArray address) { jint battery_charge, jbyteArray address) { ALOGI("%s: sBluetoothHfpInterface: %p", __func__, sBluetoothHfpInterface); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = sBluetoothHfpInterface->CindResponse( bt_status_t status = sBluetoothHfpInterface->CindResponse( service, num_active, num_held, service, num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state, signal, roam, (bluetooth::headset::bthf_call_state_t)call_state, signal, roam, battery_charge, (RawAddress*)addr); battery_charge, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed cind_response, status: %d", status); ALOGE("%s: failed, status: %d", __func__, status); } } env->ReleaseByteArrayElements(address, addr, 0); env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; Loading @@ -674,16 +704,17 @@ static jboolean atResponseStringNative(JNIEnv* env, jobject object, jstring response_str, jstring response_str, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } const char* response = env->GetStringUTFChars(response_str, nullptr); const char* response = env->GetStringUTFChars(response_str, nullptr); bt_status_t status = bt_status_t status = sBluetoothHfpInterface->FormattedAtResponse(response, (RawAddress*)addr); sBluetoothHfpInterface->FormattedAtResponse(response, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -698,14 +729,16 @@ static jboolean atResponseCodeNative(JNIEnv* env, jobject object, jint response_code, jint cmee_code, jint response_code, jint cmee_code, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = sBluetoothHfpInterface->AtResponse( bt_status_t status = sBluetoothHfpInterface->AtResponse( (bluetooth::headset::bthf_at_response_t)response_code, cmee_code, (bluetooth::headset::bthf_at_response_t)response_code, cmee_code, (RawAddress*)addr); (RawAddress*)addr); Loading @@ -721,17 +754,20 @@ static jboolean clccResponseNative(JNIEnv* env, jobject object, jint index, jboolean mpty, jstring number_str, jint type, jboolean mpty, jstring number_str, jint type, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } const char* number = nullptr; const char* number = nullptr; if (number_str) number = env->GetStringUTFChars(number_str, nullptr); if (number_str) { number = env->GetStringUTFChars(number_str, nullptr); } bt_status_t status = sBluetoothHfpInterface->ClccResponse( bt_status_t status = sBluetoothHfpInterface->ClccResponse( index, (bluetooth::headset::bthf_call_direction_t)dir, index, (bluetooth::headset::bthf_call_direction_t)dir, (bluetooth::headset::bthf_call_state_t)callStatus, (bluetooth::headset::bthf_call_state_t)callStatus, Loading @@ -744,34 +780,47 @@ static jboolean clccResponseNative(JNIEnv* env, jobject object, jint index, ALOGE("Failed sending CLCC response, status: %d", status); ALOGE("Failed sending CLCC response, status: %d", status); } } env->ReleaseByteArrayElements(address, addr, 0); env->ReleaseByteArrayElements(address, addr, 0); if (number) env->ReleaseStringUTFChars(number_str, number); if (number) { env->ReleaseStringUTFChars(number_str, number); } return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } } static jboolean phoneStateChangeNative(JNIEnv* env, jobject object, static jboolean phoneStateChangeNative(JNIEnv* env, jobject object, jint num_active, jint num_held, jint num_active, jint num_held, jint call_state, jstring number_str, jint call_state, jstring number_str, jint type) { jint type, jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); return JNI_FALSE; } const char* number = env->GetStringUTFChars(number_str, nullptr); const char* number = env->GetStringUTFChars(number_str, nullptr); bt_status_t status = sBluetoothHfpInterface->PhoneStateChange( bt_status_t status = sBluetoothHfpInterface->PhoneStateChange( num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state, num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state, number, (bluetooth::headset::bthf_call_addrtype_t)type); number, (bluetooth::headset::bthf_call_addrtype_t)type, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed report phone state change, status: %d", status); ALOGE("Failed report phone state change, status: %d", status); } } env->ReleaseStringUTFChars(number_str, number); env->ReleaseStringUTFChars(number_str, number); env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } } static jboolean setScoAllowedNative(JNIEnv* env, jobject object, static jboolean setScoAllowedNative(JNIEnv* env, jobject object, jboolean value) { jboolean value) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } bt_status_t status = sBluetoothHfpInterface->SetScoAllowed(value == JNI_TRUE); bt_status_t status = sBluetoothHfpInterface->SetScoAllowed(value == JNI_TRUE); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { ALOGE("Failed HF set sco allowed, status: %d", status); ALOGE("Failed HF set sco allowed, status: %d", status); Loading @@ -782,14 +831,16 @@ static jboolean setScoAllowedNative(JNIEnv* env, jobject object, static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value, static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, NULL); jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->SendBsir(value == JNI_TRUE, (RawAddress*)addr); sBluetoothHfpInterface->SendBsir(value == JNI_TRUE, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -802,14 +853,16 @@ static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value, static jboolean setActiveDeviceNative(JNIEnv* env, jobject object, static jboolean setActiveDeviceNative(JNIEnv* env, jobject object, jbyteArray address) { jbyteArray address) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothHfpInterface) return JNI_FALSE; if (!sBluetoothHfpInterface) { ALOGW("%s: sBluetoothHfpInterface is null", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, NULL); jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { if (!addr) { ALOGE("%s: failed to get device address", __func__); jniThrowIOException(env, EINVAL); jniThrowIOException(env, EINVAL); return JNI_FALSE; return JNI_FALSE; } } bt_status_t status = bt_status_t status = sBluetoothHfpInterface->SetActiveDevice((RawAddress*)addr); sBluetoothHfpInterface->SetActiveDevice((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { if (status != BT_STATUS_SUCCESS) { Loading @@ -831,7 +884,7 @@ static JNINativeMethod sMethods[] = { (void*)startVoiceRecognitionNative}, (void*)startVoiceRecognitionNative}, {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative}, {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative}, {"setVolumeNative", "(II[B)Z", (void*)setVolumeNative}, {"setVolumeNative", "(II[B)Z", (void*)setVolumeNative}, {"notifyDeviceStatusNative", "(IIII)Z", (void*)notifyDeviceStatusNative}, {"notifyDeviceStatusNative", "(IIII[B)Z", (void*)notifyDeviceStatusNative}, {"copsResponseNative", "(Ljava/lang/String;[B)Z", {"copsResponseNative", "(Ljava/lang/String;[B)Z", (void*)copsResponseNative}, (void*)copsResponseNative}, {"cindResponseNative", "(IIIIIII[B)Z", (void*)cindResponseNative}, {"cindResponseNative", "(IIIIIII[B)Z", (void*)cindResponseNative}, Loading @@ -840,7 +893,7 @@ static JNINativeMethod sMethods[] = { {"atResponseCodeNative", "(II[B)Z", (void*)atResponseCodeNative}, {"atResponseCodeNative", "(II[B)Z", (void*)atResponseCodeNative}, {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z", {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z", (void*)clccResponseNative}, (void*)clccResponseNative}, {"phoneStateChangeNative", "(IIILjava/lang/String;I)Z", {"phoneStateChangeNative", "(IIILjava/lang/String;I[B)Z", (void*)phoneStateChangeNative}, (void*)phoneStateChangeNative}, {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative}, {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative}, {"sendBsirNative", "(Z[B)Z", (void*)sendBsirNative}, {"sendBsirNative", "(Z[B)Z", (void*)sendBsirNative}, Loading
android/app/src/com/android/bluetooth/Utils.java +27 −0 Original line number Original line Diff line number Diff line Loading @@ -355,4 +355,31 @@ public final class Utils { public static int millsToUnit(int milliseconds) { public static int millsToUnit(int milliseconds) { return (int) (TimeUnit.MILLISECONDS.toMicros(milliseconds) / MICROS_PER_UNIT); return (int) (TimeUnit.MILLISECONDS.toMicros(milliseconds) / MICROS_PER_UNIT); } } /** * Check if we are running in BluetoothInstrumentationTest context by trying to load * com.android.bluetooth.FileSystemWriteTest. If we are not in Instrumentation test mode, this * class should not be found. Thus, the assumption is that FileSystemWriteTest must exist. * If FileSystemWriteTest is removed in the future, another test class in * BluetoothInstrumentationTest should be used instead * * @return true if in BluetoothInstrumentationTest, false otherwise */ public static boolean isInstrumentationTestMode() { try { return Class.forName("com.android.bluetooth.FileSystemWriteTest") != null; } catch (ClassNotFoundException exception) { return false; } } /** * Throws {@link IllegalStateException} if we are not in BluetoothInstrumentationTest. Useful * for ensuring certain methods only get called in BluetoothInstrumentationTest */ public static void enforceInstrumentationTestMode() { if (!isInstrumentationTestMode()) { throw new IllegalStateException("Not in BluetoothInstrumentationTest"); } } } }
android/app/src/com/android/bluetooth/btservice/AdapterService.java +9 −1 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,7 @@ import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; import com.android.bluetooth.gatt.GattService; import com.android.bluetooth.gatt.GattService; import com.android.bluetooth.sdp.SdpManager; import com.android.bluetooth.sdp.SdpManager; import com.android.internal.R; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; import com.android.internal.app.IBatteryStats; import java.io.FileDescriptor; import java.io.FileDescriptor; Loading Loading @@ -1979,7 +1980,14 @@ public class AdapterService extends Service { return deviceProp.getBluetoothClass(); return deviceProp.getBluetoothClass(); } } ParcelUuid[] getRemoteUuids(BluetoothDevice device) { /** * Get UUIDs for service supported by a remote device * * @param device the remote device that we want to get UUIDs from * @return */ @VisibleForTesting public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); if (deviceProp == null) { if (deviceProp == null) { Loading
android/app/src/com/android/bluetooth/btservice/ProfileService.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,7 @@ public abstract class ProfileService extends Service { private static final String TAG = "BluetoothProfileService"; private static final String TAG = "BluetoothProfileService"; //For Debugging only //For Debugging only private static HashMap<String, Integer> sReferenceCount = new HashMap<String, Integer>(); private static final HashMap<String, Integer> sReferenceCount = new HashMap<String, Integer>(); public static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; public static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; public static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; public static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; Loading
android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java +10 −7 Original line number Original line Diff line number Diff line Loading @@ -346,13 +346,14 @@ public class HeadsetNativeInterface { /** /** * Combined device status change notification * Combined device status change notification * * * @param device target device * @param deviceState device status object * @param deviceState device status object * @return True on success, False on failure * @return True on success, False on failure */ */ @VisibleForTesting @VisibleForTesting public boolean notifyDeviceStatus(HeadsetDeviceState deviceState) { public boolean notifyDeviceStatus(BluetoothDevice device, HeadsetDeviceState deviceState) { return notifyDeviceStatusNative(deviceState.mService, deviceState.mRoam, return notifyDeviceStatusNative(deviceState.mService, deviceState.mRoam, deviceState.mSignal, deviceState.mBatteryCharge); deviceState.mSignal, deviceState.mBatteryCharge, Utils.getByteAddress(device)); } } /** /** Loading Loading @@ -401,13 +402,15 @@ public class HeadsetNativeInterface { * This will take one of the values from BtHfCallState * This will take one of the values from BtHfCallState * 3. number & type: valid only for incoming & waiting call * 3. number & type: valid only for incoming & waiting call * * * @param device target device for this update * @param callState callstate structure * @param callState callstate structure * @return True on success, False on failure * @return True on success, False on failure */ */ @VisibleForTesting @VisibleForTesting public boolean phoneStateChange(HeadsetCallState callState) { public boolean phoneStateChange(BluetoothDevice device, HeadsetCallState callState) { return phoneStateChangeNative(callState.mNumActive, callState.mNumHeld, return phoneStateChangeNative(callState.mNumActive, callState.mNumHeld, callState.mCallState, callState.mNumber, callState.mType); callState.mCallState, callState.mNumber, callState.mType, Utils.getByteAddress(device)); } } /** /** Loading Loading @@ -472,7 +475,7 @@ public class HeadsetNativeInterface { int callState, int signal, int roam, int batteryCharge, byte[] address); int callState, int signal, int roam, int batteryCharge, byte[] address); private native boolean notifyDeviceStatusNative(int networkState, int serviceType, int signal, private native boolean notifyDeviceStatusNative(int networkState, int serviceType, int signal, int batteryCharge); int batteryCharge, byte[] address); private native boolean clccResponseNative(int index, int dir, int status, int mode, private native boolean clccResponseNative(int index, int dir, int status, int mode, boolean mpty, String number, int type, byte[] address); boolean mpty, String number, int type, byte[] address); Loading @@ -480,7 +483,7 @@ public class HeadsetNativeInterface { private native boolean copsResponseNative(String operatorName, byte[] address); private native boolean copsResponseNative(String operatorName, byte[] address); private native boolean phoneStateChangeNative(int numActive, int numHeld, int callState, private native boolean phoneStateChangeNative(int numActive, int numHeld, int callState, String number, int type); String number, int type, byte[] address); private native boolean setScoAllowedNative(boolean value); private native boolean setScoAllowedNative(boolean value); Loading