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

Commit eee0a9c7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "HFP: Add support for Multi-HFP (1/2)"

parents c6c36a6e 78434f29
Loading
Loading
Loading
Loading
+131 −78
Original line number Original line Diff line number Diff line
@@ -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;
  }
  }
@@ -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;
  }
  }
@@ -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;
  }
  }
@@ -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);
@@ -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);
@@ -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);
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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);
@@ -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);
  }
  }
@@ -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) {
@@ -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;
@@ -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) {
@@ -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);
@@ -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,
@@ -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);
@@ -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) {
@@ -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) {
@@ -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},
@@ -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},
+27 −0
Original line number Original line Diff line number Diff line
@@ -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");
        }
    }
}
}
+9 −1
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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) {
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;
+10 −7
Original line number Original line Diff line number Diff line
@@ -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));
    }
    }


    /**
    /**
@@ -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));
    }
    }


    /**
    /**
@@ -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);
@@ -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